Cosmetic changes (static and remove string spaces).
[platform/upstream/lightmediascanner.git] / src / lib / lightmediascanner_db_image.c
1 #include <lightmediascanner_db.h>
2 #include "lightmediascanner_db_private.h"
3 #include <stdlib.h>
4 #include <stdio.h>
5
6 struct lms_db_image {
7     sqlite3 *db;
8     sqlite3_stmt *insert;
9     int _references;
10 };
11
12 static lms_db_image_t *_singleton = NULL;
13
14 static int
15 _db_create_table_if_required(sqlite3 *db)
16 {
17     char *errmsg;
18     int r, ret;
19
20     errmsg = NULL;
21     r = sqlite3_exec(db,
22                      "CREATE TABLE IF NOT EXISTS images ("
23                      "id INTEGER PRIMARY KEY, "
24                      "title TEXT, "
25                      "artist TEXT, "
26                      "date INTEGER NOT NULL, "
27                      "width INTEGER NOT NULL, "
28                      "height INTEGER NOT NULL, "
29                      "orientation INTEGER NOT NULL, "
30                      "thumb_width INTEGER NOT NULL, "
31                      "thumb_height INTEGER NOT NULL, "
32                      "gps_lat REAL DEFAULT 0.0, "
33                      "gps_long REAL DEFAULT 0.0, "
34                      "gps_alt REAL DEFAULT 0.0"
35                      ")",
36                      NULL, NULL, &errmsg);
37     if (r != SQLITE_OK) {
38         fprintf(stderr, "ERROR: could not create 'images' table: %s\n", errmsg);
39         sqlite3_free(errmsg);
40         return -1;
41     }
42
43     r = sqlite3_exec(db,
44                      "CREATE INDEX IF NOT EXISTS images_date_idx ON images ("
45                      "date"
46                      ")",
47                      NULL, NULL, &errmsg);
48     if (r != SQLITE_OK) {
49         fprintf(stderr, "ERROR: could not create 'images_date_idx' index: %s\n",
50                 errmsg);
51         sqlite3_free(errmsg);
52         return -2;
53     }
54
55     ret = lms_db_create_trigger_if_not_exists(db,
56         "delete_images_on_files_deleted "
57         "DELETE ON files FOR EACH ROW BEGIN "
58         " DELETE FROM images WHERE id = OLD.id; END;");
59     if (ret != 0)
60         goto done;
61
62     ret = lms_db_create_trigger_if_not_exists(db,
63         "delete_files_on_images_deleted "
64         "DELETE ON images FOR EACH ROW BEGIN "
65         " DELETE FROM files WHERE id = OLD.id; END;");
66
67   done:
68     return ret;
69 }
70
71 lms_db_image_t *
72 lms_db_image_new(sqlite3 *db)
73 {
74     lms_db_image_t *ldi;
75
76     if (_singleton) {
77         _singleton->_references++;
78         return _singleton;
79     }
80
81     if (!db)
82         return NULL;
83
84     if (_db_create_table_if_required(db) != 0) {
85         fprintf(stderr, "ERROR: could not create table.\n");
86         return NULL;
87     }
88
89     ldi = calloc(1, sizeof(lms_db_image_t));
90     ldi->_references = 1;
91     ldi->db = db;
92
93     return ldi;
94 }
95
96 int
97 lms_db_image_start(lms_db_image_t *ldi)
98 {
99     if (!ldi)
100         return -1;
101
102     ldi->insert = lms_db_compile_stmt(ldi->db,
103         "INSERT OR REPLACE INTO images ("
104         "id, title, artist, date, width, height, orientation, "
105         "thumb_width, thumb_height, gps_lat, gps_long, gps_alt) VALUES ("
106         "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
107     if (!ldi->insert)
108         return -2;
109
110     return 0;
111 }
112
113 int
114 lms_db_image_free(lms_db_image_t *ldi)
115 {
116     if (!ldi)
117         return -1;
118
119     ldi->_references--;
120     if (ldi->_references > 0)
121         return 0;
122
123     if (ldi->insert)
124         lms_db_finalize_stmt(ldi->insert, "insert");
125
126     free(ldi);
127     _singleton = NULL;
128
129     return 0;
130 }
131
132 static int
133 _db_insert(lms_db_image_t *ldi, const struct lms_image_info *info)
134 {
135     sqlite3_stmt *stmt;
136     int r, ret;
137     unsigned long tw, th;
138
139     if (info->height < info->width) {
140         tw = 128;
141         th = (info->height * 128) / info->width;
142         if (th == 0)
143             th = 1;
144     } else if (info->height == info->width)
145         tw = th = 128;
146     else {
147         th = 128;
148         tw = (info->width * 128) / info->height;
149         if (tw == 0)
150             tw = 1;
151     }
152
153     stmt = ldi->insert;
154
155     ret = lms_db_bind_int64(stmt, 1, info->id);
156     if (ret != 0)
157         goto done;
158
159     ret = lms_db_bind_text(stmt, 2, info->title.str, info->title.len);
160     if (ret != 0)
161         goto done;
162
163     ret = lms_db_bind_text(stmt, 3, info->artist.str, info->artist.len);
164     if (ret != 0)
165         goto done;
166
167     ret = lms_db_bind_int(stmt, 4, info->date);
168     if (ret != 0)
169         goto done;
170
171     ret = lms_db_bind_int(stmt, 5, info->width);
172     if (ret != 0)
173         goto done;
174
175     ret = lms_db_bind_int(stmt, 6, info->height);
176     if (ret != 0)
177         goto done;
178
179     ret = lms_db_bind_int(stmt, 7, info->orientation);
180     if (ret != 0)
181         goto done;
182
183     ret = lms_db_bind_int(stmt, 8, tw);
184     if (ret != 0)
185         goto done;
186
187     ret = lms_db_bind_int(stmt, 9, th);
188     if (ret != 0)
189         goto done;
190
191     ret = lms_db_bind_double(stmt, 10, info->gps.latitude);
192     if (ret != 0)
193         goto done;
194
195     ret = lms_db_bind_double(stmt, 11, info->gps.longitude);
196     if (ret != 0)
197         goto done;
198
199     ret = lms_db_bind_double(stmt, 12, info->gps.altitude);
200     if (ret != 0)
201         goto done;
202
203     r = sqlite3_step(stmt);
204     if (r != SQLITE_DONE) {
205         fprintf(stderr, "ERROR: could not insert image info: %s\n",
206                 sqlite3_errmsg(ldi->db));
207         ret = -13;
208         goto done;
209     }
210
211     ret = 0;
212
213   done:
214     lms_db_reset_stmt(stmt);
215
216     return ret;
217 }
218
219 int
220 lms_db_image_add(lms_db_image_t *ldi, struct lms_image_info *info)
221 {
222     if (!ldi)
223         return -1;
224     if (!info)
225         return -2;
226     if (info->id < 1)
227         return -3;
228
229     return _db_insert(ldi, info);
230 }