Mercurial > hg > sv-dependency-builds
comparison src/libsndfile-1.0.25/regtest/database.c @ 0:c7265573341e
Import initial set of sources
author | Chris Cannam |
---|---|
date | Mon, 18 Mar 2013 14:12:14 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c7265573341e |
---|---|
1 /* | |
2 ** Copyright (C) 2005-2011 Erik de Castro Lopo | |
3 ** | |
4 ** This program is free software; you can redistribute it and/or modify | |
5 ** it under the terms of the GNU General Public License as published by | |
6 ** the Free Software Foundation; either version 2 of the License, or | |
7 ** (at your option) any later version. | |
8 ** | |
9 ** This program is distributed in the hope that it will be useful, | |
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ** GNU General Public License for more details. | |
13 ** | |
14 ** You should have received a copy of the GNU General Public License | |
15 ** along with this program; if not, write to the Free Software | |
16 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
17 */ | |
18 | |
19 #include "config.h" | |
20 | |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 #include <unistd.h> | |
24 #include <string.h> | |
25 #include <fcntl.h> | |
26 #include <sys/stat.h> | |
27 | |
28 #include <sndfile.h> | |
29 | |
30 #include "regtest.h" | |
31 | |
32 #if HAVE_SQLITE3 | |
33 | |
34 #include <sqlite3.h> | |
35 | |
36 typedef struct | |
37 { sqlite3 *sql ; | |
38 | |
39 int count ; | |
40 int ekey_max ; | |
41 | |
42 /* Filename and pathname for file. */ | |
43 char filename [256] ; | |
44 char pathname [512] ; | |
45 | |
46 /* Storage for createding SQL commands. Must be larger than logbuf below. */ | |
47 char cmdbuf [1 << 15] ; | |
48 | |
49 /* Storage for log buffer retrieved from SNDFILE* .*/ | |
50 char logbuf [1 << 14] ; | |
51 | |
52 } REGTEST_DB ; | |
53 | |
54 /* In checksum.c */ | |
55 int calc_checksum (SNDFILE * file, const SF_INFO * info) ; | |
56 | |
57 static void get_filename_pathname (REGTEST_DB * db, const char *filepath) ; | |
58 static void single_quote_replace (char * buf) ; | |
59 | |
60 static int get_ekey_from_filename (REGTEST_DB * db, const char *filepath) ; | |
61 static int get_filename_pathname_by_ekey (REGTEST_DB * db, int ekey) ; | |
62 static int check_file_by_ekey (REGTEST_DB * db, int ekey) ; | |
63 | |
64 static int count_callback (REGTEST_DB * db, int argc, char **argv, char **colname) ; | |
65 static int ekey_max_callback (REGTEST_DB * db, int argc, char **argv, char **colname) ; | |
66 static int callback (void *unused, int argc, char **argv, char **colname) ; | |
67 | |
68 REG_DB * | |
69 db_open (const char * db_name) | |
70 { REGTEST_DB * db ; | |
71 int err ; | |
72 | |
73 if ((db = malloc (sizeof (REGTEST_DB))) == NULL) | |
74 { perror ("malloc") ; | |
75 exit (1) ; | |
76 } ; | |
77 | |
78 if ((err = sqlite3_open (db_name, &(db->sql))) != 0) | |
79 { printf ("Can't open database: %s\n", sqlite3_errmsg (db->sql)) ; | |
80 sqlite3_close (db->sql) ; | |
81 free (db) ; | |
82 exit (1) ; | |
83 } ; | |
84 | |
85 return (REG_DB *) db ; | |
86 } /* db_open */ | |
87 | |
88 int | |
89 db_create (const char * db_name) | |
90 { REGTEST_DB * db ; | |
91 const char *cmd ; | |
92 char * errmsg = NULL ; | |
93 int err ; | |
94 | |
95 db = (REGTEST_DB *) db_open (db_name) ; | |
96 | |
97 cmd = "create table sndfile (ekey INTEGER PRIMARY KEY," | |
98 "fname VARCHAR(1)," | |
99 "fpath VARCHAR(1)," | |
100 "srate INTEGER," | |
101 "frames VARCHAR(1)," | |
102 "channels INTEGER," | |
103 "format VARCHAR(1)," | |
104 "checksum VARCHAR(1)," | |
105 "logbuf VARCHAR(1)" | |
106 ");" ; | |
107 | |
108 err = sqlite3_exec (db->sql, cmd, callback, 0, &errmsg) ; | |
109 if (err != SQLITE_OK) | |
110 printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ; | |
111 | |
112 sqlite3_close (db->sql) ; | |
113 free (db) ; | |
114 | |
115 return 0 ; | |
116 } /* db_create */ | |
117 | |
118 int | |
119 db_close (REG_DB * db_handle) | |
120 { REGTEST_DB * db ; | |
121 | |
122 db = (REGTEST_DB *) db_handle ; | |
123 | |
124 sqlite3_close (db->sql) ; | |
125 free (db) ; | |
126 | |
127 return 0 ; | |
128 } /* db_close */ | |
129 | |
130 /*============================================================================== | |
131 */ | |
132 | |
133 int | |
134 db_file_exists (REG_DB * db_handle, const char * filename) | |
135 { REGTEST_DB * db ; | |
136 const char * cptr ; | |
137 char * errmsg ; | |
138 int err ; | |
139 | |
140 db = (REGTEST_DB *) db_handle ; | |
141 | |
142 if ((cptr = strrchr (filename, '/')) != NULL) | |
143 filename = cptr + 1 ; | |
144 | |
145 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "select fname from sndfile where fname='%s'", filename) ; | |
146 | |
147 db->count = 0 ; | |
148 err = sqlite3_exec (db->sql, db->cmdbuf, (sqlite3_callback) count_callback, db, &errmsg) ; | |
149 if (err == 0 && db->count == 1) | |
150 return 1 ; | |
151 | |
152 return 0 ; | |
153 } /* db_file_exists */ | |
154 | |
155 int | |
156 db_add_file (REG_DB * db_handle, const char * filepath) | |
157 { REGTEST_DB * db ; | |
158 SNDFILE * sndfile ; | |
159 SF_INFO info ; | |
160 char * errmsg ; | |
161 int err, checksum ; | |
162 | |
163 db = (REGTEST_DB *) db_handle ; | |
164 | |
165 get_filename_pathname (db, filepath) ; | |
166 | |
167 if (db_file_exists (db_handle, filepath)) | |
168 { printf (" %s : already in database\n", db->filename) ; | |
169 return 0 ; | |
170 } ; | |
171 | |
172 memset (&info, 0, sizeof (info)) ; | |
173 sndfile = sf_open (db->pathname, SFM_READ, &info) ; | |
174 sf_command (sndfile, SFC_GET_LOG_INFO, db->logbuf, sizeof (db->logbuf)) ; | |
175 checksum = (sndfile == NULL) ? 0 : calc_checksum (sndfile, &info) ; | |
176 sf_close (sndfile) ; | |
177 | |
178 if (sndfile == NULL) | |
179 { printf (" %s : could not open : %s\n", db->filename, sf_strerror (NULL)) ; | |
180 puts (db->logbuf) ; | |
181 return 1 ; | |
182 } ; | |
183 | |
184 single_quote_replace (db->logbuf) ; | |
185 | |
186 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "insert into sndfile " | |
187 "(fname, fpath, srate, frames, channels, format, checksum, logbuf) values" | |
188 "('%s','%s',%d,'%ld', %d, '0x%08x', '0x%08x', '%s');", | |
189 db->filename, db->pathname, info.samplerate, (long) info.frames, info.channels, info.format, checksum, db->logbuf) ; | |
190 | |
191 if (strlen (db->cmdbuf) >= sizeof (db->cmdbuf) - 1) | |
192 { printf ("strlen (db->cmdbuf) too long.\n") ; | |
193 exit (1) ; | |
194 } ; | |
195 | |
196 err = sqlite3_exec (db->sql, db->cmdbuf, callback, 0, &errmsg) ; | |
197 if (err != SQLITE_OK) | |
198 { printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ; | |
199 puts (db->cmdbuf) ; | |
200 } ; | |
201 | |
202 return 0 ; | |
203 } /* db_add_file */ | |
204 | |
205 int | |
206 db_check_file (REG_DB * db_handle, const char * filepath) | |
207 { REGTEST_DB * db ; | |
208 int ekey ; | |
209 | |
210 if (db_file_exists (db_handle, filepath) == 0) | |
211 { printf ("\nFile not in database.\n\n") ; | |
212 exit (0) ; | |
213 } ; | |
214 | |
215 db = (REGTEST_DB *) db_handle ; | |
216 | |
217 ekey = get_ekey_from_filename (db, filepath) ; | |
218 | |
219 return check_file_by_ekey (db, ekey) ; | |
220 } /* db_check_file */ | |
221 | |
222 /*============================================================================== | |
223 */ | |
224 | |
225 int | |
226 db_check_all (REG_DB * db_handle) | |
227 { REGTEST_DB * db ; | |
228 char * errmsg ; | |
229 int err, ekey ; | |
230 | |
231 db = (REGTEST_DB *) db_handle ; | |
232 | |
233 db->ekey_max = 0 ; | |
234 | |
235 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "select ekey from sndfile") ; | |
236 | |
237 err = sqlite3_exec (db->sql, db->cmdbuf, (sqlite3_callback) ekey_max_callback, db, &errmsg) ; | |
238 if (err != SQLITE_OK) | |
239 { printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ; | |
240 puts (db->cmdbuf) ; | |
241 } ; | |
242 | |
243 for (ekey = 1 ; ekey <= db->ekey_max ; ekey++) | |
244 if (get_filename_pathname_by_ekey (db, ekey) != 0) | |
245 check_file_by_ekey (db, ekey) ; | |
246 | |
247 return 0 ; | |
248 } /* db_check_all */ | |
249 | |
250 | |
251 int | |
252 db_list_all (REG_DB * db_handle) | |
253 { | |
254 printf ("%s : %p\n", __func__, db_handle) ; | |
255 return 0 ; | |
256 } /* db_list_all */ | |
257 | |
258 int | |
259 db_del_entry (REG_DB * db_handle, const char * entry) | |
260 { | |
261 printf ("%s : %p %s\n", __func__, db_handle, entry) ; | |
262 return 0 ; | |
263 } /* db_del_entry */ | |
264 | |
265 /*============================================================================== | |
266 */ | |
267 | |
268 static int | |
269 get_ekey_from_filename (REGTEST_DB * db, const char *filepath) | |
270 { char * errmsg, **result ; | |
271 int err, ekey = 0, rows, cols ; | |
272 | |
273 get_filename_pathname (db, filepath) ; | |
274 | |
275 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "select ekey from sndfile where fname='%s'", db->filename) ; | |
276 | |
277 err = sqlite3_get_table (db->sql, db->cmdbuf, &result, &rows, &cols, &errmsg) ; | |
278 if (err != SQLITE_OK) | |
279 { printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ; | |
280 puts (db->cmdbuf) ; | |
281 } ; | |
282 | |
283 if (cols != 1 || rows != 1) | |
284 { printf ("Bad juju!! rows = %d cols = %d\n", rows, cols) ; | |
285 exit (1) ; | |
286 } ; | |
287 | |
288 ekey = strtol (result [1], NULL, 10) ; | |
289 | |
290 sqlite3_free_table (result) ; | |
291 | |
292 return ekey ; | |
293 } /* get_ekey_from_filename */ | |
294 | |
295 static int | |
296 get_filename_pathname_by_ekey (REGTEST_DB * db, int ekey) | |
297 { char *errmsg, **result ; | |
298 int err, rows, cols ; | |
299 | |
300 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "select fname,fpath from sndfile where ekey='%d'", ekey) ; | |
301 | |
302 err = sqlite3_get_table (db->sql, db->cmdbuf, &result, &rows, &cols, &errmsg) ; | |
303 if (err != SQLITE_OK) | |
304 { printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ; | |
305 puts (db->cmdbuf) ; | |
306 return 0 ; | |
307 } ; | |
308 | |
309 if (cols != 2 || rows != 1) | |
310 { printf ("\nError (%s %d) : rows = %d cols = %d\n", __func__, __LINE__, rows, cols) ; | |
311 exit (1) ; | |
312 } ; | |
313 | |
314 snprintf (db->filename, sizeof (db->filename), "%s", result [2]) ; | |
315 snprintf (db->pathname, sizeof (db->pathname), "%s", result [3]) ; | |
316 | |
317 sqlite3_free_table (result) ; | |
318 | |
319 return 1 ; | |
320 } /* get_filename_pathname_by_ekey */ | |
321 | |
322 static int | |
323 check_file_by_ekey (REGTEST_DB * db, int ekey) | |
324 { SNDFILE * sndfile ; | |
325 SF_INFO info ; | |
326 char * errmsg, **result ; | |
327 int err, k, rows, cols, checksum ; | |
328 | |
329 printf (" %s : ", db->filename) ; | |
330 fflush (stdout) ; | |
331 | |
332 memset (&info, 0, sizeof (info)) ; | |
333 sndfile = sf_open (db->pathname, SFM_READ, &info) ; | |
334 sf_command (sndfile, SFC_GET_LOG_INFO, db->logbuf, sizeof (db->logbuf)) ; | |
335 checksum = (sndfile == NULL) ? 0 : calc_checksum (sndfile, &info) ; | |
336 sf_close (sndfile) ; | |
337 | |
338 if (sndfile == NULL) | |
339 { printf ("\n\nError : Could not open '%s' : %s\n", db->pathname, sf_strerror (NULL)) ; | |
340 puts (db->logbuf) ; | |
341 exit (1) ; | |
342 } ; | |
343 | |
344 single_quote_replace (db->logbuf) ; | |
345 | |
346 snprintf (db->cmdbuf, sizeof (db->cmdbuf), "select fname,srate,frames,channels,format," | |
347 "checksum,logbuf from sndfile where ekey='%d'", ekey) ; | |
348 | |
349 err = sqlite3_get_table (db->sql, db->cmdbuf, &result, &rows, &cols, &errmsg) ; | |
350 if (err != SQLITE_OK) | |
351 { printf ("Line %d : SQL error: %s\n", __LINE__, errmsg) ; | |
352 puts (db->cmdbuf) ; | |
353 } ; | |
354 | |
355 for (k = 0 ; k < cols ; k++) | |
356 { if (strcmp (result [k], "fname") == 0) | |
357 { if (strcmp (result [k + cols], db->filename) == 0) | |
358 continue ; | |
359 printf ("\n\nError : fname doesn't match : %s != %s\n", result [k + cols], db->filename) ; | |
360 } ; | |
361 | |
362 if (strcmp (result [k], "srate") == 0) | |
363 { if (strtol (result [k + cols], NULL, 10) == info.samplerate) | |
364 continue ; | |
365 printf ("\n\nError : srate doesn't match : %s == %d\n", result [k + cols], info.samplerate) ; | |
366 } ; | |
367 | |
368 if (strcmp (result [k], "frames") == 0) | |
369 { if (strtoll (result [k + cols], NULL, 10) == info.frames) | |
370 continue ; | |
371 printf ("\n\nError : frames doesn't match : %s == %ld\n", result [k + cols], (long) info.frames) ; | |
372 } ; | |
373 | |
374 if (strcmp (result [k], "channels") == 0) | |
375 { if (strtol (result [k + cols], NULL, 10) == info.channels) | |
376 continue ; | |
377 printf ("\n\nError : channels doesn't match : %s == %d\n", result [k + cols], info.channels) ; | |
378 } ; | |
379 | |
380 if (strcmp (result [k], "format") == 0) | |
381 { if (strtol (result [k + cols], NULL, 16) == info.format) | |
382 continue ; | |
383 printf ("\n\nError : format doesn't match : %s == 0x%08x\n", result [k + cols], info.format) ; | |
384 } ; | |
385 | |
386 if (strcmp (result [k], "checksum") == 0) | |
387 { int db_val = (int) strtoll (result [k + cols], NULL, 16) ; | |
388 | |
389 if (db_val == checksum) | |
390 continue ; | |
391 printf ("\n\nError : checksum doesn't match : 0x%08x == 0x%08x\n", db_val, checksum) ; | |
392 } ; | |
393 | |
394 if (strcmp (result [k], "logbuf") == 0) | |
395 continue ; | |
396 | |
397 printf ("\nHere is the old logubuffer :\n\n%s\n\nand the new :\n\n%s\n\n", result [2 * cols - 1], db->logbuf) ; | |
398 exit (1) ; | |
399 } ; | |
400 | |
401 sqlite3_free_table (result) ; | |
402 | |
403 puts ("ok") ; | |
404 | |
405 return 0 ; | |
406 } /* check_file_by_ekey */ | |
407 | |
408 /*============================================================================== | |
409 */ | |
410 | |
411 static void | |
412 get_filename_pathname (REGTEST_DB * db, const char *filepath) | |
413 { const char * cptr ; | |
414 int slen ; | |
415 | |
416 if (filepath [0] != '/') | |
417 { memset (db->pathname, 0, sizeof (db->pathname)) ; | |
418 if (getcwd (db->pathname, sizeof (db->pathname)) == NULL) | |
419 { perror ("\ngetcwd failed") ; | |
420 exit (1) ; | |
421 } ; | |
422 | |
423 slen = strlen (db->pathname) ; | |
424 db->pathname [slen ++] = '/' ; | |
425 snprintf (db->pathname + slen, sizeof (db->pathname) - slen, "%s", filepath) ; | |
426 } | |
427 else | |
428 snprintf (db->pathname, sizeof (db->pathname), "%s", filepath) ; | |
429 | |
430 if ((cptr = strrchr (db->pathname, '/')) == NULL) | |
431 { printf ("\nError : bad pathname %s\n", filepath) ; | |
432 exit (1) ; | |
433 } ; | |
434 | |
435 snprintf (db->filename, sizeof (db->filename), "%s", cptr + 1) ; | |
436 } /* get filename_pathname */ | |
437 | |
438 static void | |
439 single_quote_replace (char * buf) | |
440 { while ((buf = strchr (buf, '\'')) != 0) | |
441 buf [0] = '"' ; | |
442 } /* single_quote_replace */ | |
443 | |
444 static int | |
445 count_callback (REGTEST_DB * db, int argc, char **argv, char **colname) | |
446 { db->count ++ ; | |
447 | |
448 (void) argc ; | |
449 (void) argv ; | |
450 (void) colname ; | |
451 return 0 ; | |
452 } /* count_callback */ | |
453 | |
454 static int | |
455 ekey_max_callback (REGTEST_DB * db, int argc, char **argv, char **unused) | |
456 { int ekey ; | |
457 | |
458 (void) argc ; | |
459 (void) unused ; | |
460 | |
461 ekey = strtol (argv [0], NULL, 10) ; | |
462 if (ekey > db->ekey_max) | |
463 db->ekey_max = ekey ; | |
464 | |
465 return 0 ; | |
466 } /* ekey_max_callback */ | |
467 | |
468 static int | |
469 callback (void *unused, int argc, char **argv, char **colname) | |
470 { int k ; | |
471 | |
472 (void) unused ; | |
473 | |
474 for (k = 0 ; k < argc ; k++) | |
475 printf ("%s = %s\n", colname [k], argv [k] ? argv [k] : "NULL") ; | |
476 | |
477 printf ("\n") ; | |
478 | |
479 return 0 ; | |
480 } /* callback */ | |
481 | |
482 #else | |
483 | |
484 int dummy (void) ; | |
485 | |
486 int | |
487 dummy (void) | |
488 { /* | |
489 ** Empty dummy fnction so tha compiler doesn't winge about an | |
490 ** empty file. | |
491 */ | |
492 return 0 ; | |
493 } /* dummy */ | |
494 | |
495 #endif |