Automatically set parent family in individual, when adding child to the family.
[familia.git] / src / storage / storage.c
1 #include <stdlib.h>
2
3 #include "storage.h"
4
5 #include "../debug.h"
6
7 struct familia_storage * _familia_storage_current;
8
9 extern void _familia_storage_positions_init();
10 extern void _familia_storage_positions_free();
11
12 struct familia_storage * familia_storage_get_current()
13 {
14         return _familia_storage_current;
15 }
16
17 void familia_storage_set_current(struct familia_storage * storage)
18 {
19         _familia_storage_current = storage;
20 }
21
22 struct familia_storage * familia_storage_new()
23 {
24         struct familia_storage * storage = NULL;
25         storage = malloc(sizeof(struct familia_storage));
26
27         if (!storage) {
28                 debug("["__FILE__ "] There was a problem with allocating memory for storage.\n");
29                 return NULL;
30         }
31
32         storage->individuals = NULL;
33         storage->individuals_no = 0;
34         storage->families = NULL;
35         storage->families_no = 0;
36
37         _familia_storage_positions_init();
38
39         return storage;
40 }
41
42 void familia_storage_free(struct familia_storage * storage)
43 {
44         unsigned int i = 0;
45
46         if (storage->individuals_no) {
47                 for (i = 0; i < storage->individuals_no; i++) {
48                         familia_individual_free(storage->individuals[i]);
49                         storage->individuals[i] = NULL;
50                 }
51                 free(storage->individuals);
52                 storage->individuals = NULL;
53                 storage->individuals_no = 0;
54         }
55
56         if (storage->families_no) {
57                 for (i = 0; i < storage->families_no; i++) {
58                         familia_family_free(storage->families[i]);
59                         storage->families[i] = NULL;
60                 }
61                 free(storage->families);
62                 storage->families = NULL;
63                 storage->families_no = 0;
64         }
65
66         _familia_storage_positions_free();
67 }
68
69 void familia_storage_add_individual(struct familia_storage * storage, struct familia_individual * individual)
70 {
71         struct familia_individual ** tmp = NULL;
72         int size = (storage->individuals_no + 1);
73
74         if (individual) {
75                 tmp = realloc(storage->individuals, size * sizeof(struct familia_individual *));
76                 
77                 if (tmp) {
78                         storage->individuals = tmp;
79                         storage->individuals[storage->individuals_no] = individual;
80                         storage->individuals_no++;
81                 }
82                 else {
83                         debug("["__FILE__ "] There were problems with allocating memory for individual.\n");
84                 }
85         }
86 }
87
88 struct familia_individual * familia_storage_get_individual_by_id(struct familia_storage * storage, unsigned int id)
89 {
90         if (storage->individuals_no < id) {
91                 debug("["__FILE__ "Trying to get not existing individual!\n");
92                 return NULL;
93         }
94         return storage->individuals[id];
95 }
96
97 void familia_storage_remove_individual_by_id(struct familia_storage * storage, unsigned int id)
98 {
99         unsigned int i = 0;
100         int found = 0;
101         struct familia_individual ** tmp = NULL;
102         
103         if (storage->individuals_no < id) {
104                 debug("["__FILE__ "] Trying to remove not existing individual!\n");
105                 return;
106         }
107
108         for (i = 0; i < storage->individuals_no; i++) {
109                 if (storage->individuals[i]->id == id) {
110                         found = 1;
111                         familia_individual_free(storage->individuals[i]);
112                         storage->individuals[i] = NULL;
113                 }
114
115                 /*
116                  * If family has been found, reorder rest of files to avoid
117                  * NULL pointers inside array.
118                  */
119                 if (found && (i < storage->individuals_no - 1)) {
120                         storage->individuals[i] = storage->individuals[i + 1];
121                 }
122         }
123         
124         if (found) {
125                 tmp = realloc(storage->individuals,
126                         (storage->families_no) * sizeof(struct familia_family *));
127
128                 if (tmp) {
129                         storage->individuals = tmp;
130                 }
131                 storage->individuals_no--;
132         }
133 }
134
135 void familia_storage_add_family(struct familia_storage * storage, struct familia_family * family)
136 {
137         struct familia_family ** tmp = NULL;
138         int size = (storage->families_no + 1);
139
140         if (family) {
141                 tmp = realloc(storage->families, size * sizeof(struct familia_family *));
142                 
143                 if (tmp) {
144                         storage->families = tmp;
145                         storage->families[storage->families_no] = family;
146                         storage->families_no++;
147                 }
148                 else {
149                         debug("["__FILE__ "] There were problems with allocating memory for family.\n");
150                 }
151         }
152 }
153
154 struct familia_family * familia_storage_get_family_by_id(struct familia_storage * storage, unsigned int id)
155 {
156         if (storage->families_no < id) {
157                 debug("["__FILE__ "Trying to get not existing family!\n");
158                 return NULL;
159         }
160         return storage->families[id];
161 }
162
163 void familia_storage_remove_family_by_id(struct familia_storage * storage, unsigned int id)
164 {
165         unsigned int i = 0;
166         int found = 0;
167         struct familia_family ** tmp = NULL;
168         
169         if (storage->families_no < id) {
170                 debug("["__FILE__ "] Trying to remove not existing family!\n");
171                 return;
172         }
173
174         for (i = 0; i < storage->families_no; i++) {
175                 if (storage->families[i]->id == id) {
176                         found = 1;
177                         familia_family_free(storage->families[i]);
178                         storage->families[i] = NULL;
179                 }
180
181                 /*
182                  * If family has been found, reorder rest of files to avoid
183                  * NULL pointers inside array.
184                  */
185                 if (found && (i < storage->families_no - 1)) {
186                         storage->families[i] = storage->families[i + 1];
187                 }
188         }
189         
190         if (found) {
191                 tmp = realloc(storage->families,
192                         (storage->families_no) * sizeof(struct familia_family *));
193
194                 if (tmp) {
195                         storage->families = tmp;
196                 }
197                 storage->families_no--;
198         }
199 }
200