00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "system.h"
00037
00038 #include <rpmio.h>
00039 #include <rpmlog.h>
00040 #include <rpmmacro.h>
00041 #include <rpmurl.h>
00042
00043 #include <rpmtag.h>
00044 #define _RPMDB_INTERNAL
00045 #include <rpmdb.h>
00046
00047 #include <sqlite3.h>
00048
00049 #include "debug.h"
00050
00051 #if defined(__LCLINT__)
00052 #define UINT32_T u_int32_t
00053 #else
00054 #define UINT32_T rpmuint32_t
00055 #endif
00056
00057
00058
00059
00060
00061 #if defined(__QNXNTO__)
00062 typedef rpmuint32_t u_int32_t;
00063 #endif
00064
00065
00066 static int _debug = 0;
00067
00068
00069 struct _sql_db_s; typedef struct _sql_db_s SQL_DB;
00070 struct _sql_dbcursor_s; typedef struct _sql_dbcursor_s *SCP_t;
00071
00072 struct _sql_db_s {
00073 sqlite3 * db;
00074 int transaction;
00075 };
00076
00077 struct _sql_dbcursor_s {
00078
00079 DB *dbp;
00080
00081
00082 char * cmd;
00083
00084 sqlite3_stmt *pStmt;
00085 const char * pzErrmsg;
00086
00087
00088
00089 char ** av;
00090
00091 size_t * avlen;
00092 int nalloc;
00093 int ac;
00094 int rx;
00095 int nr;
00096 int nc;
00097
00098 int all;
00099
00100 DBT ** keys;
00101 int nkeys;
00102
00103 int count;
00104
00105
00106 void * lkey;
00107
00108 void * ldata;
00109
00110 int used;
00111 };
00112
00113
00114 union _dbswap {
00115 rpmuint32_t ui;
00116 unsigned char uc[4];
00117 };
00118
00119
00120 #define _DBSWAP(_a) \
00121 { unsigned char _b, *_c = (_a).uc; \
00122 _b = _c[3]; _c[3] = _c[0]; _c[0] = _b; \
00123 _b = _c[2]; _c[2] = _c[1]; _c[1] = _b; \
00124 }
00125
00126
00127 static unsigned int endian = 0x11223344;
00128
00129
00130 static const char * sqlCwd = NULL;
00131
00132 static int sqlInRoot = 0;
00133
00134 static void enterChroot(dbiIndex dbi)
00135
00136
00137 {
00138 char * currDir = NULL;
00139 int xx;
00140
00141 if ((dbi->dbi_root[0] == '/' && dbi->dbi_root[1] == '\0') || dbi->dbi_rpmdb->db_chrootDone || sqlInRoot)
00142
00143 return;
00144
00145 if (_debug)
00146 fprintf(stderr, "sql:chroot(%s)\n", dbi->dbi_root);
00147
00148 {
00149 int currDirLen = 0;
00150
00151 do {
00152 currDirLen += 128;
00153 currDir = xrealloc(currDir, currDirLen);
00154 memset(currDir, 0, currDirLen);
00155 } while (getcwd(currDir, currDirLen) == NULL && errno == ERANGE);
00156 }
00157
00158 sqlCwd = currDir;
00159
00160 xx = Chdir("/");
00161
00162
00163 xx = Chroot(dbi->dbi_root);
00164
00165 assert(xx == 0);
00166 sqlInRoot=1;
00167 }
00168
00169 static void leaveChroot(dbiIndex dbi)
00170
00171
00172 {
00173 int xx;
00174
00175 if ((dbi->dbi_root[0] == '/' && dbi->dbi_root[1] == '\0') || dbi->dbi_rpmdb->db_chrootDone || !sqlInRoot)
00176
00177 return;
00178
00179 if (_debug)
00180 fprintf(stderr, "sql:chroot(.)\n");
00181
00182
00183 xx = Chroot(".");
00184
00185 assert(xx == 0);
00186 if (sqlCwd != NULL) {
00187
00188 xx = Chdir(sqlCwd);
00189
00190 sqlCwd = _free(sqlCwd);
00191 }
00192
00193 sqlInRoot = 0;
00194 }
00195
00196 static void dbg_scp(void *ptr)
00197
00198
00199 {
00200 SCP_t scp = ptr;
00201
00202 if (_debug)
00203 fprintf(stderr, "\tscp %p [%d:%d] av %p avlen %p nr [%d:%d] nc %d all %d\n", scp, scp->ac, scp->nalloc, scp->av, scp->avlen, scp->rx, scp->nr, scp->nc, scp->all);
00204
00205 }
00206
00207 static void dbg_keyval(const char * msg, dbiIndex dbi, DBC * dbcursor,
00208 DBT * key, DBT * data, unsigned int flags)
00209
00210
00211 {
00212
00213 if (!_debug) return;
00214
00215 fprintf(stderr, "%s on %s (%p,%p,%p,0x%x)", msg, dbi->dbi_subfile, dbcursor, key, data, flags);
00216
00217
00218 if (key != NULL && key->data != NULL) {
00219 fprintf(stderr, " key 0x%x[%d]", *(unsigned int *)key->data, key->size);
00220 if (dbi->dbi_rpmtag == RPMTAG_NAME)
00221 fprintf(stderr, " \"%s\"", (const char *)key->data);
00222 }
00223 if (data != NULL && data->data != NULL)
00224 fprintf(stderr, " data 0x%x[%d]", *(unsigned int *)data->data, data->size);
00225
00226 fprintf(stderr, "\n");
00227 if (dbcursor != NULL)
00228 dbg_scp(dbcursor);
00229 }
00230
00231
00232 static SCP_t scpResetKeys( SCP_t scp)
00233
00234 {
00235 int ix;
00236
00237 if (_debug)
00238 fprintf(stderr, "*** scpResetKeys(%p)\n", scp);
00239 dbg_scp(scp);
00240
00241 for ( ix =0 ; ix < scp->nkeys ; ix++ ) {
00242 scp->keys[ix]->data = _free(scp->keys[ix]->data);
00243
00244 scp->keys[ix] = _free(scp->keys[ix]);
00245
00246 }
00247 scp->keys = _free(scp->keys);
00248 scp->nkeys = 0;
00249
00250 return scp;
00251 }
00252
00253
00254 static SCP_t scpResetAv( SCP_t scp)
00255
00256 {
00257 int xx;
00258
00259 if (_debug)
00260 fprintf(stderr, "*** scpResetAv(%p)\n", scp);
00261 dbg_scp(scp);
00262
00263 if (scp->av != NULL) {
00264 if (scp->nalloc <= 0) {
00265
00266 sqlite3_free_table(scp->av);
00267 scp->av = NULL;
00268 scp->nalloc = 0;
00269 } else {
00270
00271
00272 for (xx = 0; xx < scp->ac; xx++)
00273 scp->av[xx] = _free(scp->av[xx]);
00274
00275 if (scp->av != NULL)
00276 memset(scp->av, 0, scp->nalloc * sizeof(*scp->av));
00277 if (scp->avlen != NULL)
00278 memset(scp->avlen, 0, scp->nalloc * sizeof(*scp->avlen));
00279 scp->av = _free(scp->av);
00280 scp->avlen = _free(scp->avlen);
00281 scp->nalloc = 0;
00282 }
00283 } else
00284 scp->nalloc = 0;
00285 scp->ac = 0;
00286 scp->nr = 0;
00287 scp->nc = 0;
00288
00289 return scp;
00290 }
00291
00292
00293 static SCP_t scpReset( SCP_t scp)
00294
00295 {
00296 int xx;
00297
00298 if (_debug)
00299 fprintf(stderr, "*** scpReset(%p)\n", scp);
00300 dbg_scp(scp);
00301
00302 if (scp->cmd) {
00303 sqlite3_free(scp->cmd);
00304 scp->cmd = NULL;
00305 }
00306 if (scp->pStmt) {
00307 xx = sqlite3_reset(scp->pStmt);
00308 if (xx) rpmlog(RPMLOG_WARNING, "reset %d\n", xx);
00309 xx = sqlite3_finalize(scp->pStmt);
00310 if (xx) rpmlog(RPMLOG_WARNING, "finalize %d\n", xx);
00311 scp->pStmt = NULL;
00312 }
00313
00314 scp = scpResetAv(scp);
00315
00316 scp->rx = 0;
00317 return scp;
00318 }
00319
00320
00321 static SCP_t scpFree( SCP_t scp)
00322
00323 {
00324 scp = scpReset(scp);
00325 scp = scpResetKeys(scp);
00326 scp->av = _free(scp->av);
00327 scp->avlen = _free(scp->avlen);
00328
00329 if (_debug)
00330 fprintf(stderr, "*** scpFree(%p)\n", scp);
00331 scp = _free(scp);
00332 return NULL;
00333 }
00334
00335 static SCP_t scpNew(DB * dbp)
00336
00337 {
00338 SCP_t scp = xcalloc(1, sizeof(*scp));
00339
00340 scp->dbp = dbp;
00341
00342
00343 scp->used = 0;
00344
00345 scp->lkey = NULL;
00346 scp->ldata = NULL;
00347
00348 if (_debug)
00349 fprintf(stderr, "*** scpNew(%p)\n", scp);
00350 return scp;
00351 }
00352
00353 static int sql_step(dbiIndex dbi, SCP_t scp)
00354
00355 {
00356 int swapped = dbiByteSwapped(dbi);
00357 const char * cname;
00358 const char * vtype;
00359 size_t nb;
00360 int loop;
00361 int need;
00362 int rc;
00363 int i;
00364
00365 scp->nc = sqlite3_column_count(scp->pStmt);
00366
00367 if (scp->nr == 0 && scp->av != NULL)
00368 need = 2 * scp->nc;
00369 else
00370 need = scp->nc;
00371
00372
00373 if (!scp->ac && !need && !scp->nalloc)
00374 need++;
00375
00376 if (scp->ac + need >= scp->nalloc) {
00377
00378 scp->nalloc = 2 * scp->nalloc + need + 4;
00379 scp->av = xrealloc(scp->av, scp->nalloc * sizeof(*scp->av));
00380 scp->avlen = xrealloc(scp->avlen, scp->nalloc * sizeof(*scp->avlen));
00381 }
00382
00383 if (scp->av != NULL && scp->nr == 0) {
00384 for (i = 0; i < scp->nc; i++) {
00385 scp->av[scp->ac] = xstrdup(sqlite3_column_name(scp->pStmt, i));
00386 if (scp->avlen) scp->avlen[scp->ac] = strlen(scp->av[scp->ac]) + 1;
00387 scp->ac++;
00388 assert(scp->ac <= scp->nalloc);
00389 }
00390 }
00391
00392
00393 loop = 1;
00394 while (loop) {
00395 rc = sqlite3_step(scp->pStmt);
00396 switch (rc) {
00397 case SQLITE_DONE:
00398 if (_debug)
00399 fprintf(stderr, "sqlite3_step: DONE scp %p [%d:%d] av %p avlen %p\n", scp, scp->ac, scp->nalloc, scp->av, scp->avlen);
00400 loop = 0;
00401 break;
00402 case SQLITE_ROW:
00403 if (scp->av != NULL)
00404 for (i = 0; i < scp->nc; i++) {
00405
00406 if (scp->ac + need >= scp->nalloc) {
00407
00408 scp->nalloc = 2 * scp->nalloc + need + 4;
00409 scp->av = xrealloc(scp->av, scp->nalloc * sizeof(*scp->av));
00410 scp->avlen = xrealloc(scp->avlen, scp->nalloc * sizeof(*scp->avlen));
00411 }
00412 assert(scp->av != NULL);
00413 assert(scp->avlen != NULL);
00414
00415 cname = sqlite3_column_name(scp->pStmt, i);
00416 vtype = sqlite3_column_decltype(scp->pStmt, i);
00417 nb = 0;
00418
00419 if (!strcmp(vtype, "blob")) {
00420 const void * v = sqlite3_column_blob(scp->pStmt, i);
00421 nb = sqlite3_column_bytes(scp->pStmt, i);
00422 if (_debug)
00423 fprintf(stderr, "\t%d %s %s %p[%d]\n", i, cname, vtype, v, (int)nb);
00424 if (nb > 0) {
00425 void * t = xmalloc(nb);
00426 scp->av[scp->ac] = memcpy(t, v, nb);
00427 scp->avlen[scp->ac] = nb;
00428 scp->ac++;
00429 }
00430 } else
00431 if (!strcmp(vtype, "double")) {
00432 double v = sqlite3_column_double(scp->pStmt, i);
00433 nb = sizeof(v);
00434 if (_debug)
00435 fprintf(stderr, "\t%d %s %s %g\n", i, cname, vtype, v);
00436 if (nb > 0) {
00437 scp->av[scp->ac] = memcpy(xmalloc(nb), &v, nb);
00438 scp->avlen[scp->ac] = nb;
00439 assert(swapped == 0);
00440 scp->ac++;
00441 }
00442 } else
00443 if (!strcmp(vtype, "int")) {
00444 rpmint32_t v = sqlite3_column_int(scp->pStmt, i);
00445 nb = sizeof(v);
00446 if (_debug)
00447 fprintf(stderr, "\t%d %s %s %d\n", i, cname, vtype, (int) v);
00448 if (nb > 0) {
00449 scp->av[scp->ac] = memcpy(xmalloc(nb), &v, nb);
00450 scp->avlen[scp->ac] = nb;
00451 if (swapped == 1) {
00452 union _dbswap dbswap;
00453 memcpy(&dbswap.ui, scp->av[scp->ac], sizeof(dbswap.ui));
00454 _DBSWAP(dbswap);
00455 memcpy(scp->av[scp->ac], &dbswap.ui, sizeof(dbswap.ui));
00456 }
00457 scp->ac++;
00458 }
00459 } else
00460 if (!strcmp(vtype, "int64")) {
00461 int64_t v = sqlite3_column_int64(scp->pStmt, i);
00462 nb = sizeof(v);
00463 if (_debug)
00464 fprintf(stderr, "\t%d %s %s %ld\n", i, cname, vtype, (long)v);
00465 if (nb > 0) {
00466 scp->av[scp->ac] = memcpy(xmalloc(nb), &v, nb);
00467 scp->avlen[scp->ac] = nb;
00468 assert(swapped == 0);
00469 scp->ac++;
00470 }
00471 } else
00472 if (!strcmp(vtype, "text")) {
00473 const char * v = (const char *)sqlite3_column_text(scp->pStmt, i);
00474 nb = strlen(v) + 1;
00475 if (_debug)
00476 fprintf(stderr, "\t%d %s %s \"%s\"\n", i, cname, vtype, v);
00477 if (nb > 0) {
00478 scp->av[scp->ac] = memcpy(xmalloc(nb), v, nb);
00479 scp->avlen[scp->ac] = nb;
00480 scp->ac++;
00481 }
00482 }
00483 assert(scp->ac <= scp->nalloc);
00484 }
00485 scp->nr++;
00486 break;
00487 case SQLITE_BUSY:
00488 fprintf(stderr, "sqlite3_step: BUSY %d\n", rc);
00489 break;
00490 case SQLITE_ERROR:
00491 fprintf(stderr, "sqlite3_step: ERROR %d -- %s\n", rc, scp->cmd);
00492 fprintf(stderr, " %s (%d)\n",
00493 sqlite3_errmsg(((SQL_DB*)dbi->dbi_db)->db), sqlite3_errcode(((SQL_DB*)dbi->dbi_db)->db));
00494
00495 fprintf(stderr, " cwd '%s'\n", getcwd(NULL,0));
00496
00497 loop = 0;
00498 break;
00499 case SQLITE_MISUSE:
00500 fprintf(stderr, "sqlite3_step: MISUSE %d\n", rc);
00501 loop = 0;
00502 break;
00503 default:
00504 fprintf(stderr, "sqlite3_step: rc %d\n", rc);
00505 loop = 0;
00506 break;
00507 }
00508 }
00509
00510
00511 if (rc == SQLITE_DONE)
00512 rc = SQLITE_OK;
00513
00514 return rc;
00515 }
00516
00517 static int sql_bind_key(dbiIndex dbi, SCP_t scp, int pos, DBT * key)
00518
00519 {
00520 int swapped = dbiByteSwapped(dbi);
00521 int rc = 0;
00522 union _dbswap dbswap;
00523
00524 assert(key->data != NULL);
00525 switch (dbi->dbi_rpmtag) {
00526 case RPMDBI_PACKAGES:
00527 { unsigned int hnum;
00528 assert(key->size == sizeof(rpmuint32_t));
00529 memcpy(&hnum, key->data, sizeof(hnum));
00530
00531 if (swapped == 1) {
00532 memcpy(&dbswap.ui, &hnum, sizeof(dbswap.ui));
00533 _DBSWAP(dbswap);
00534 memcpy(&hnum, &dbswap.ui, sizeof(dbswap.ui));
00535 }
00536 rc = sqlite3_bind_int(scp->pStmt, pos, hnum);
00537 } break;
00538 default:
00539 switch (tagType(dbi->dbi_rpmtag) & RPM_MASK_TYPE) {
00540 case RPM_BIN_TYPE:
00541
00542 rc = sqlite3_bind_blob(scp->pStmt, pos, key->data, key->size, SQLITE_STATIC);
00543
00544 break;
00545 case RPM_UINT8_TYPE:
00546 { unsigned char i;
00547 assert(key->size == sizeof(unsigned char));
00548 assert(swapped == 0);
00549 memcpy(&i, key->data, sizeof(i));
00550 rc = sqlite3_bind_int(scp->pStmt, pos, (int) i);
00551 } break;
00552 case RPM_UINT16_TYPE:
00553 { unsigned short i;
00554 assert(key->size == sizeof(rpmuint16_t));
00555 assert(swapped == 0);
00556 memcpy(&i, key->data, sizeof(i));
00557 rc = sqlite3_bind_int(scp->pStmt, pos, (int) i);
00558 } break;
00559 case RPM_UINT64_TYPE:
00560 assert(0);
00561 break;
00562 case RPM_UINT32_TYPE:
00563 default:
00564 { unsigned int i;
00565 assert(key->size == sizeof(rpmuint32_t));
00566 memcpy(&i, key->data, sizeof(i));
00567
00568 if (swapped == 1)
00569 {
00570 memcpy(&dbswap.ui, &i, sizeof(dbswap.ui));
00571 _DBSWAP(dbswap);
00572 memcpy(&i, &dbswap.ui, sizeof(dbswap.ui));
00573 }
00574 rc = sqlite3_bind_int(scp->pStmt, pos, i);
00575 } break;
00576 case RPM_STRING_TYPE:
00577 case RPM_STRING_ARRAY_TYPE:
00578 case RPM_I18NSTRING_TYPE:
00579
00580 rc = sqlite3_bind_text(scp->pStmt, pos, key->data, key->size, SQLITE_STATIC);
00581
00582 break;
00583 }
00584 }
00585
00586 return rc;
00587 }
00588
00589 static int sql_bind_data( dbiIndex dbi, SCP_t scp,
00590 int pos, DBT * data)
00591
00592 {
00593 int rc;
00594
00595 assert(data->data != NULL);
00596
00597 rc = sqlite3_bind_blob(scp->pStmt, pos, data->data, data->size, SQLITE_STATIC);
00598
00599
00600 return rc;
00601 }
00602
00603
00604
00605
00606
00607
00608 static int sql_startTransaction(dbiIndex dbi)
00609
00610 {
00611 SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db;
00612 int rc = 0;
00613
00614
00615 if (!sqldb->transaction) {
00616 char * pzErrmsg;
00617 rc = sqlite3_exec(sqldb->db, "BEGIN TRANSACTION;", NULL, NULL, &pzErrmsg);
00618
00619 if (_debug)
00620 fprintf(stderr, "Begin %s SQL transaction %s (%d)\n",
00621 dbi->dbi_subfile, pzErrmsg, rc);
00622
00623 if (rc == 0)
00624 sqldb->transaction = 1;
00625 }
00626
00627 return rc;
00628 }
00629
00630 static int sql_endTransaction(dbiIndex dbi)
00631
00632 {
00633 SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db;
00634 int rc=0;
00635
00636
00637 if (sqldb->transaction) {
00638 char * pzErrmsg;
00639 rc = sqlite3_exec(sqldb->db, "END TRANSACTION;", NULL, NULL, &pzErrmsg);
00640
00641 if (_debug)
00642 fprintf(stderr, "End %s SQL transaction %s (%d)\n",
00643 dbi->dbi_subfile, pzErrmsg, rc);
00644
00645 if (rc == 0)
00646 sqldb->transaction = 0;
00647 }
00648
00649 return rc;
00650 }
00651
00652 static int sql_commitTransaction(dbiIndex dbi, int flag)
00653
00654 {
00655 SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db;
00656 int rc = 0;
00657
00658
00659 if ( sqldb->transaction ) {
00660 char * pzErrmsg;
00661 rc = sqlite3_exec(sqldb->db, "COMMIT;", NULL, NULL, &pzErrmsg);
00662
00663 if (_debug)
00664 fprintf(stderr, "Commit %s SQL transaction(s) %s (%d)\n",
00665 dbi->dbi_subfile, pzErrmsg, rc);
00666
00667 sqldb->transaction=0;
00668
00669
00670 if ( flag == 0 )
00671 rc = sql_startTransaction(dbi);
00672 }
00673
00674 return rc;
00675 }
00676
00677 static int sql_busy_handler(void * dbi_void, int time)
00678
00679 {
00680
00681 dbiIndex dbi = (dbiIndex) dbi_void;
00682
00683
00684 rpmlog(RPMLOG_WARNING, _("Unable to get lock on db %s, retrying... (%d)\n"),
00685 dbi->dbi_file, time);
00686
00687 (void) sleep(1);
00688
00689 return 1;
00690 }
00691
00692
00693
00699 static int sql_initDB(dbiIndex dbi)
00700
00701
00702 {
00703 SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db;
00704 SCP_t scp = scpNew(dbi->dbi_db);
00705 char cmd[BUFSIZ];
00706 int rc = 0;
00707
00708 if (dbi->dbi_tmpdir) {
00709 const char *root;
00710 const char *tmpdir;
00711 int xx;
00712 root = (dbi->dbi_root ? dbi->dbi_root : dbi->dbi_rpmdb->db_root);
00713 if ((root[0] == '/' && root[1] == '\0') || dbi->dbi_rpmdb->db_chrootDone)
00714 root = NULL;
00715
00716 tmpdir = rpmGenPath(root, dbi->dbi_tmpdir, NULL);
00717
00718 sprintf(cmd, "PRAGMA temp_store_directory = '%s';", tmpdir);
00719 xx = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg);
00720 tmpdir = _free(tmpdir);
00721 }
00722 if (dbi->dbi_eflags & DB_EXCL) {
00723 int xx;
00724 sprintf(cmd, "PRAGMA locking_mode = EXCLUSIVE;");
00725 xx = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg);
00726 }
00727 if (dbi->dbi_pagesize > 0) {
00728 int xx;
00729 sprintf(cmd, "PRAGMA cache_size = %d;", dbi->dbi_cachesize);
00730 xx = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg);
00731 }
00732 if (dbi->dbi_cachesize > 0) {
00733 int xx;
00734 sprintf(cmd, "PRAGMA page_size = %d;", dbi->dbi_pagesize);
00735 xx = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg);
00736 }
00737
00738
00739 sprintf(cmd,
00740 "SELECT name FROM 'sqlite_master' WHERE type='table' and name='%s';",
00741 dbi->dbi_subfile);
00742
00743 rc = sqlite3_get_table(sqldb->db, cmd,
00744 &scp->av, &scp->nr, &scp->nc, (char **)&scp->pzErrmsg);
00745
00746 if (rc)
00747 goto exit;
00748
00749 if (scp->nr < 1) {
00750 const char * valtype = "blob";
00751 const char * keytype;
00752
00753 switch (dbi->dbi_rpmtag) {
00754 case RPMDBI_PACKAGES:
00755 keytype = "int UNIQUE PRIMARY KEY";
00756 valtype = "blob";
00757 break;
00758 default:
00759 switch (tagType(dbi->dbi_rpmtag) & RPM_MASK_TYPE) {
00760 case RPM_BIN_TYPE:
00761 default:
00762 keytype = "blob UNIQUE";
00763 break;
00764 case RPM_UINT8_TYPE:
00765 case RPM_UINT16_TYPE:
00766 case RPM_UINT32_TYPE:
00767 case RPM_UINT64_TYPE:
00768 keytype = "int UNIQUE";
00769 break;
00770 case RPM_STRING_TYPE:
00771 case RPM_STRING_ARRAY_TYPE:
00772 case RPM_I18NSTRING_TYPE:
00773 keytype = "text UNIQUE";
00774 break;
00775 }
00776 }
00777 if (_debug)
00778 fprintf(stderr, "\t%s(%d) type(%d) keytype %s\n", tagName(dbi->dbi_rpmtag), dbi->dbi_rpmtag, (tagType(dbi->dbi_rpmtag) & RPM_MASK_TYPE), keytype);
00779 sprintf(cmd, "CREATE %sTABLE '%s' (key %s, value %s)",
00780 dbi->dbi_temporary ? "TEMPORARY " : "",
00781 dbi->dbi_subfile, keytype, valtype);
00782 rc = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg);
00783 if (rc)
00784 goto exit;
00785
00786 sprintf(cmd, "CREATE %sTABLE 'db_info' (endian TEXT)",
00787 dbi->dbi_temporary ? "TEMPORARY " : "");
00788 rc = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg);
00789 if (rc)
00790 goto exit;
00791
00792 sprintf(cmd, "INSERT INTO 'db_info' values('%u')", (unsigned)((union _dbswap *)&endian)->uc[0]);
00793 rc = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg);
00794 if (rc)
00795 goto exit;
00796 }
00797
00798 if (dbi->dbi_no_fsync) {
00799 int xx;
00800 sprintf(cmd, "PRAGMA synchronous = OFF;");
00801 xx = sqlite3_exec(sqldb->db, cmd, NULL, NULL, (char **)&scp->pzErrmsg);
00802 }
00803
00804 exit:
00805 if (rc)
00806 rpmlog(RPMLOG_WARNING, "Unable to initDB %s (%d)\n",
00807 scp->pzErrmsg, rc);
00808
00809 scp = scpFree(scp);
00810
00811 return rc;
00812 }
00813
00821 static int sql_cclose (dbiIndex dbi, DBC * dbcursor,
00822 unsigned int flags)
00823
00824
00825 {
00826 SCP_t scp = (SCP_t)dbcursor;
00827 int rc;
00828
00829 if (_debug)
00830 fprintf(stderr, "==> sql_cclose(%p)\n", scp);
00831
00832 if (scp->lkey)
00833 scp->lkey = _free(scp->lkey);
00834
00835 if (scp->ldata)
00836 scp->ldata = _free(scp->ldata);
00837
00838 enterChroot(dbi);
00839
00840 if (flags == DB_WRITECURSOR)
00841 rc = sql_commitTransaction(dbi, 1);
00842 else
00843 rc = sql_endTransaction(dbi);
00844
00845
00846 scp = scpFree(scp);
00847
00848
00849 leaveChroot(dbi);
00850
00851 return rc;
00852 }
00853
00860 static int sql_close( dbiIndex dbi, unsigned int flags)
00861
00862
00863 {
00864 SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db;
00865 int rc = 0;
00866
00867 if (sqldb) {
00868 enterChroot(dbi);
00869
00870
00871 rc = sql_commitTransaction(dbi, 1);
00872
00873 (void) sqlite3_close(sqldb->db);
00874
00875 rpmlog(RPMLOG_DEBUG, D_("closed sql db %s\n"),
00876 dbi->dbi_subfile);
00877
00878 #if defined(MAYBE)
00879 if (dbi->dbi_temporary && !(dbi->dbi_eflags & DB_PRIVATE)) {
00880 const char * dbhome = NULL;
00881 urltype ut = urlPath(dbi->dbi_home, &dbhome);
00882 const char * dbfname = rpmGenPath(dbhome, dbi->dbi_file, NULL);
00883 int xx = (dbfname ? Unlink(dbfname) : 0);
00884 ut = ut; xx = xx;
00885 dbfname = _free(dbfname);
00886 }
00887 #endif
00888
00889 dbi->dbi_stats = _free(dbi->dbi_stats);
00890 dbi->dbi_file = _free(dbi->dbi_file);
00891 dbi->dbi_db = _free(dbi->dbi_db);
00892
00893 leaveChroot(dbi);
00894 }
00895
00896 dbi = _free(dbi);
00897
00898 return rc;
00899 }
00900
00908 static int sql_open(rpmdb rpmdb, rpmTag rpmtag, dbiIndex * dbip)
00909
00910
00911 {
00912
00913 extern struct _dbiVec sqlitevec;
00914
00915
00916 const char * urlfn = NULL;
00917 const char * root;
00918 const char * home;
00919 const char * dbhome;
00920 const char * dbfile;
00921 const char * dbfname;
00922 const char * sql_errcode;
00923 mode_t umask_safed = 0002;
00924 dbiIndex dbi;
00925 SQL_DB * sqldb;
00926 size_t len;
00927 int rc = 0;
00928 int xx;
00929
00930 if (dbip)
00931 *dbip = NULL;
00932
00933
00934
00935
00936
00937 if ((dbi = db3New(rpmdb, rpmtag)) == NULL)
00938
00939 return 1;
00940
00941
00942
00943
00944
00945
00946 root = rpmdb->db_root;
00947 home = rpmdb->db_home;
00948
00949 dbi->dbi_root = root;
00950 dbi->dbi_home = home;
00951
00952 dbfile = tagName(dbi->dbi_rpmtag);
00953
00954 enterChroot(dbi);
00955
00956
00957
00958
00959
00960 {
00961 char * t;
00962 len = strlen(dbfile);
00963 t = xcalloc(len + 1, sizeof(*t));
00964 (void) stpcpy( t, dbfile );
00965 dbi->dbi_file = t;
00966
00967 dbi->dbi_subfile = t;
00968
00969 }
00970
00971 dbi->dbi_mode = O_RDWR;
00972
00973
00974
00975
00976
00977
00978 urlfn = rpmGenPath(NULL, home, NULL);
00979
00980 (void) urlPath(urlfn, &dbhome);
00981
00982
00983
00984
00985 (void) rpmioMkpath(dbhome, 0755, getuid(), getgid());
00986
00987 if (dbi->dbi_eflags & DB_PRIVATE)
00988 dbfname = xstrdup(":memory:");
00989 else
00990 dbfname = rpmGenPath(dbhome, dbi->dbi_file, NULL);
00991
00992 rpmlog(RPMLOG_DEBUG, D_("opening sql db %s (%s) mode=0x%x\n"),
00993 dbfname, dbi->dbi_subfile, dbi->dbi_mode);
00994
00995
00996 sqldb = xcalloc(1, sizeof(*sqldb));
00997
00998 sql_errcode = NULL;
00999
01000 if (dbi->dbi_perms)
01001
01002 umask_safed = umask(~((mode_t)(dbi->dbi_perms)));
01003
01004 xx = sqlite3_open(dbfname, &sqldb->db);
01005 if (dbi->dbi_perms) {
01006 if ((0644 & dbi->dbi_perms) != dbi->dbi_perms) {
01007
01008 (void) Chmod(dbfname, dbi->dbi_perms);
01009 }
01010
01011 (void) umask(umask_safed);
01012
01013 }
01014 if (xx != SQLITE_OK)
01015 sql_errcode = sqlite3_errmsg(sqldb->db);
01016
01017 if (sqldb->db)
01018 (void) sqlite3_busy_handler(sqldb->db, &sql_busy_handler, dbi);
01019
01020 sqldb->transaction = 0;
01021
01022 dbi->dbi_db = (DB *)sqldb;
01023
01024 if (sql_errcode != NULL) {
01025 rpmlog(RPMLOG_DEBUG, D_("Unable to open database: %s\n"), sql_errcode);
01026 rc = EINVAL;
01027 }
01028
01029
01030 if (rc == 0)
01031 rc = sql_initDB(dbi);
01032
01033 if (rc == 0 && dbi->dbi_db != NULL && dbip != NULL) {
01034 dbi->dbi_vec = &sqlitevec;
01035 *dbip = dbi;
01036 } else {
01037 (void) sql_close(dbi, 0);
01038 }
01039
01040 urlfn = _free(urlfn);
01041 dbfname = _free(dbfname);
01042
01043
01044 leaveChroot(dbi);
01045
01046
01047 return rc;
01048 }
01049
01056 static int sql_sync (dbiIndex dbi, unsigned int flags)
01057
01058
01059 {
01060 int rc = 0;
01061
01062 enterChroot(dbi);
01063 rc = sql_commitTransaction(dbi, 0);
01064 leaveChroot(dbi);
01065
01066 return rc;
01067 }
01068
01077 static int sql_copen (dbiIndex dbi,
01078 DB_TXN * txnid,
01079 DBC ** dbcp, unsigned int flags)
01080
01081
01082 {
01083 SCP_t scp = scpNew(dbi->dbi_db);
01084 DBC * dbcursor = (DBC *)scp;
01085 int rc = 0;
01086
01087 if (_debug)
01088 fprintf(stderr, "==> sql_copen(%s) tag %d type %d scp %p\n", tagName(dbi->dbi_rpmtag), dbi->dbi_rpmtag, (tagType(dbi->dbi_rpmtag) & RPM_MASK_TYPE), scp);
01089
01090 enterChroot(dbi);
01091
01092
01093 if (flags == DB_WRITECURSOR)
01094 rc = sql_startTransaction(dbi);
01095
01096 if (dbcp)
01097 *dbcp = dbcursor;
01098 else
01099 (void) sql_cclose(dbi, dbcursor, 0);
01100
01101 leaveChroot(dbi);
01102
01103 return rc;
01104 }
01105
01115 static int sql_cdel (dbiIndex dbi, DBC * dbcursor, DBT * key,
01116 DBT * data, unsigned int flags)
01117
01118
01119 {
01120 SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db;
01121 SCP_t scp = scpNew(dbi->dbi_db);
01122 int rc = 0;
01123
01124 dbg_keyval("sql_cdel", dbi, dbcursor, key, data, flags);
01125 enterChroot(dbi);
01126
01127 scp->cmd = sqlite3_mprintf("DELETE FROM '%q' WHERE key=? AND value=?;",
01128 dbi->dbi_subfile);
01129
01130 rc = sqlite3_prepare(sqldb->db, scp->cmd, (int)strlen(scp->cmd), &scp->pStmt, &scp->pzErrmsg);
01131 if (rc) rpmlog(RPMLOG_WARNING, "cdel(%s) prepare %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc);
01132 rc = sql_bind_key(dbi, scp, 1, key);
01133 if (rc) rpmlog(RPMLOG_WARNING, "cdel(%s) bind key %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc);
01134 rc = sql_bind_data(dbi, scp, 2, data);
01135 if (rc) rpmlog(RPMLOG_WARNING, "cdel(%s) bind data %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc);
01136
01137 rc = sql_step(dbi, scp);
01138 if (rc) rpmlog(RPMLOG_WARNING, "cdel(%s) sql_step rc %d\n", dbi->dbi_subfile, rc);
01139
01140 scp = scpFree(scp);
01141
01142 leaveChroot(dbi);
01143
01144 return rc;
01145 }
01146
01156 static int sql_cget (dbiIndex dbi, DBC * dbcursor, DBT * key,
01157 DBT * data, unsigned int flags)
01158
01159
01160 {
01161 SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db;
01162 SCP_t scp = (SCP_t)dbcursor;
01163 int rc = 0;
01164 int ix;
01165
01166 assert(dbcursor != NULL);
01167 dbg_keyval("sql_cget", dbi, dbcursor, key, data, flags);
01168
01169 enterChroot(dbi);
01170
01171
01172
01173
01174
01175 if (_debug)
01176 fprintf(stderr, "\tcget(%s) scp %p rc %d flags %d av %p\n",
01177 dbi->dbi_subfile, scp, rc, flags, scp->av);
01178 if ( flags == DB_SET || scp->used == 0 ) {
01179 scp->used = 1;
01180 scp = scpReset(scp);
01181
01182
01183
01184
01185
01186
01187 if ( key->size == 0) {
01188 scp->all = 1;
01189
01190
01191
01192
01193
01194
01195 #ifdef DYING
01196
01197 assert(dbi->dbi_rpmtag == RPMDBI_PACKAGES);
01198 #endif
01199
01200 switch (dbi->dbi_rpmtag) {
01201 case RPMDBI_PACKAGES:
01202 scp->cmd = sqlite3_mprintf("SELECT key FROM '%q' ORDER BY key;",
01203 dbi->dbi_subfile);
01204 break;
01205 default:
01206 scp->cmd = sqlite3_mprintf("SELECT key FROM '%q';",
01207 dbi->dbi_subfile);
01208 break;
01209 }
01210 rc = sqlite3_prepare(sqldb->db, scp->cmd, (int)strlen(scp->cmd), &scp->pStmt, &scp->pzErrmsg);
01211 if (rc) rpmlog(RPMLOG_WARNING, "cget(%s) sequential prepare %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc);
01212
01213 rc = sql_step(dbi, scp);
01214 if (rc) rpmlog(RPMLOG_WARNING, "cget(%s) sequential sql_step rc %d\n", dbi->dbi_subfile, rc);
01215
01216 scp = scpResetKeys(scp);
01217 scp->nkeys = scp->nr;
01218 scp->keys = xcalloc(scp->nkeys, sizeof(*scp->keys));
01219 for (ix = 0; ix < scp->nkeys; ix++) {
01220 scp->keys[ix] = xmalloc(sizeof(*scp->keys[0]));
01221 scp->keys[ix]->size = (UINT32_T) scp->avlen[ix+1];
01222 scp->keys[ix]->data = xmalloc(scp->keys[ix]->size);
01223 memcpy(scp->keys[ix]->data, scp->av[ix+1], scp->avlen[ix+1]);
01224 }
01225 } else {
01226
01227
01228
01229 scp = scpResetKeys(scp);
01230 scp->nkeys = 1;
01231 scp->keys = xcalloc(scp->nkeys, sizeof(*scp->keys));
01232 scp->keys[0] = xmalloc(sizeof(*scp->keys[0]));
01233 scp->keys[0]->size = key->size;
01234 scp->keys[0]->data = xmalloc(scp->keys[0]->size);
01235 memcpy(scp->keys[0]->data, key->data, key->size);
01236 }
01237
01238 scp = scpReset(scp);
01239
01240
01241 scp->cmd = sqlite3_mprintf("SELECT value FROM '%q' WHERE key=?;", dbi->dbi_subfile);
01242 rc = sqlite3_prepare(sqldb->db, scp->cmd, (int)strlen(scp->cmd), &scp->pStmt, &scp->pzErrmsg);
01243
01244 if (rc) rpmlog(RPMLOG_WARNING, "cget(%s) prepare %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc);
01245 }
01246
01247 scp = scpResetAv(scp);
01248
01249
01250 if ((scp->rx + 1) > scp->nkeys )
01251 rc = DB_NOTFOUND;
01252
01253 if (rc != 0)
01254 goto exit;
01255
01256
01257 rc = sql_bind_key(dbi, scp, 1, scp->keys[scp->rx]);
01258 if (rc) rpmlog(RPMLOG_WARNING, "cget(%s) key bind %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc);
01259
01260 rc = sql_step(dbi, scp);
01261 if (rc) rpmlog(RPMLOG_WARNING, "cget(%s) sql_step rc %d\n", dbi->dbi_subfile, rc);
01262
01263 rc = sqlite3_reset(scp->pStmt);
01264 if (rc) rpmlog(RPMLOG_WARNING, "reset %d\n", rc);
01265
01266
01267 assert(scp->nr < 2);
01268
01269 if (scp->nr == 0 && scp->all == 0)
01270 rc = DB_NOTFOUND;
01271
01272 if (rc != 0)
01273 goto exit;
01274
01275
01276 if (scp->all) {
01277
01278
01279 assert(scp->nr == 1);
01280
01281 if ( scp->lkey ) {
01282 scp->lkey = _free(scp->lkey);
01283 }
01284
01285 key->size = scp->keys[scp->rx]->size;
01286 key->data = xmalloc(key->size);
01287 if (! (key->flags & DB_DBT_MALLOC))
01288 scp->lkey = key->data;
01289
01290 (void) memcpy(key->data, scp->keys[scp->rx]->data, key->size);
01291 }
01292
01293
01294 switch (dbi->dbi_rpmtag) {
01295 default:
01296 if ( scp->ldata ) {
01297 scp->ldata = _free(scp->ldata);
01298 }
01299
01300 data->size = (UINT32_T) scp->avlen[1];
01301 data->data = xmalloc(data->size);
01302 if (! (data->flags & DB_DBT_MALLOC) )
01303 scp->ldata = data->data;
01304
01305 (void) memcpy(data->data, scp->av[1], data->size);
01306 }
01307
01308 scp->rx++;
01309
01310
01311 if (_debug)
01312 fprintf(stderr, "\tcget(%s) found key 0x%x (%d)\n", dbi->dbi_subfile,
01313 key->data == NULL ? 0 : *(unsigned int *)key->data, key->size);
01314 if (_debug)
01315 fprintf(stderr, "\tcget(%s) found data 0x%x (%d)\n", dbi->dbi_subfile,
01316 key->data == NULL ? 0 : *(unsigned int *)data->data, data->size);
01317
01318 exit:
01319 if (rc == DB_NOTFOUND) {
01320 if (_debug)
01321 fprintf(stderr, "\tcget(%s) not found\n", dbi->dbi_subfile);
01322 }
01323
01324 leaveChroot(dbi);
01325
01326 return rc;
01327 }
01328
01338 static int sql_cput (dbiIndex dbi, DBC * dbcursor, DBT * key,
01339 DBT * data, unsigned int flags)
01340
01341
01342 {
01343 SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db;
01344 SCP_t scp = scpNew(dbi->dbi_db);
01345 int rc = 0;
01346
01347 dbg_keyval("sql_cput", dbi, dbcursor, key, data, flags);
01348
01349 enterChroot(dbi);
01350
01351 switch (dbi->dbi_rpmtag) {
01352 default:
01353 scp->cmd = sqlite3_mprintf("INSERT OR REPLACE INTO '%q' VALUES(?, ?);",
01354 dbi->dbi_subfile);
01355 rc = sqlite3_prepare(sqldb->db, scp->cmd, (int)strlen(scp->cmd), &scp->pStmt, &scp->pzErrmsg);
01356 if (rc) rpmlog(RPMLOG_WARNING, "cput(%s) prepare %s (%d)\n",dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc);
01357 rc = sql_bind_key(dbi, scp, 1, key);
01358 if (rc) rpmlog(RPMLOG_WARNING, "cput(%s) key bind %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc);
01359 rc = sql_bind_data(dbi, scp, 2, data);
01360 if (rc) rpmlog(RPMLOG_WARNING, "cput(%s) data bind %s (%d)\n", dbi->dbi_subfile, sqlite3_errmsg(sqldb->db), rc);
01361
01362 rc = sql_step(dbi, scp);
01363 if (rc) rpmlog(RPMLOG_WARNING, "cput(%s) sql_step rc %d\n", dbi->dbi_subfile, rc);
01364
01365 break;
01366 }
01367
01368 scp = scpFree(scp);
01369
01370 leaveChroot(dbi);
01371
01372 return rc;
01373 }
01374
01380 static int sql_byteswapped (dbiIndex dbi)
01381
01382
01383 {
01384 SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db;
01385 SCP_t scp = scpNew(dbi->dbi_db);
01386 int sql_rc, rc = 0;
01387 union _dbswap db_endian;
01388
01389 enterChroot(dbi);
01390
01391
01392 sql_rc = sqlite3_get_table(sqldb->db, "SELECT endian FROM 'db_info';",
01393 &scp->av, &scp->nr, &scp->nc, (char **)&scp->pzErrmsg);
01394
01395
01396 if (sql_rc == 0 && scp->nr > 0) {
01397 assert(scp->av != NULL);
01398 db_endian.uc[0] = (unsigned char) strtol(scp->av[1], NULL, 10);
01399
01400 if ( db_endian.uc[0] == ((union _dbswap *)&endian)->uc[0] )
01401 rc = 0;
01402 else
01403 rc = 1;
01404
01405 } else {
01406 if ( sql_rc ) {
01407 rpmlog(RPMLOG_DEBUG, D_("db_info failed %s (%d)\n"),
01408 scp->pzErrmsg, sql_rc);
01409 }
01410 rpmlog(RPMLOG_WARNING, "Unable to determine DB endian.\n");
01411 }
01412
01413 scp = scpFree(scp);
01414
01415 leaveChroot(dbi);
01416
01417 return rc;
01418 }
01419
01420
01421
01422
01423
01424
01425
01426
01435 static int sql_associate ( dbiIndex dbi,
01436 dbiIndex dbisecondary,
01437 int (*callback) (DB *, const DBT *, const DBT *, DBT *),
01438 unsigned int flags)
01439
01440 {
01441 if (_debug)
01442 fprintf(stderr, "*** sql_associate:\n");
01443 return EINVAL;
01444 }
01445
01454 static int sql_join ( dbiIndex dbi,
01455 DBC ** curslist,
01456 DBC ** dbcp,
01457 unsigned int flags)
01458
01459
01460 {
01461 if (_debug)
01462 fprintf(stderr, "*** sql_join:\n");
01463 return EINVAL;
01464 }
01465
01474 static int sql_cdup ( dbiIndex dbi,
01475 DBC * dbcursor,
01476 DBC ** dbcp,
01477 unsigned int flags)
01478
01479
01480 {
01481 if (_debug)
01482 fprintf(stderr, "*** sql_cdup:\n");
01483 return EINVAL;
01484 }
01485
01496 static int sql_cpget ( dbiIndex dbi,
01497 DBC * dbcursor,
01498 DBT * key,
01499 DBT * pkey,
01500 DBT * data,
01501 unsigned int flags)
01502
01503
01504 {
01505 if (_debug)
01506 fprintf(stderr, "*** sql_cpget:\n");
01507 return EINVAL;
01508 }
01509
01518 static int sql_ccount ( dbiIndex dbi,
01519 DBC * dbcursor,
01520 unsigned int * countp,
01521 unsigned int flags)
01522
01523
01524 {
01525 if (_debug)
01526 fprintf(stderr, "*** sql_ccount:\n");
01527 return EINVAL;
01528 }
01529
01536 static int sql_stat (dbiIndex dbi, unsigned int flags)
01537
01538
01539 {
01540 SQL_DB * sqldb = (SQL_DB *) dbi->dbi_db;
01541 SCP_t scp = scpNew(dbi->dbi_db);
01542 int rc = 0;
01543 long nkeys = -1;
01544
01545 enterChroot(dbi);
01546
01547 dbi->dbi_stats = _free(dbi->dbi_stats);
01548
01549
01550 dbi->dbi_stats = xcalloc(1, sizeof(DB_HASH_STAT));
01551
01552
01553 scp->cmd = sqlite3_mprintf("SELECT COUNT('key') FROM '%q';", dbi->dbi_subfile);
01554
01555 rc = sqlite3_get_table(sqldb->db, scp->cmd,
01556 &scp->av, &scp->nr, &scp->nc, (char **)&scp->pzErrmsg);
01557
01558
01559 if ( rc == 0 && scp->nr > 0) {
01560 assert(scp->av != NULL);
01561 nkeys = strtol(scp->av[1], NULL, 10);
01562
01563 rpmlog(RPMLOG_DEBUG, D_(" stat on %s nkeys %ld\n"),
01564 dbi->dbi_subfile, nkeys);
01565 } else {
01566 if ( rc ) {
01567 rpmlog(RPMLOG_DEBUG, D_("stat failed %s (%d)\n"),
01568 scp->pzErrmsg, rc);
01569 }
01570 }
01571
01572 if (nkeys < 0)
01573 nkeys = 4096;
01574
01575 ((DB_HASH_STAT *)(dbi->dbi_stats))->hash_nkeys = nkeys;
01576
01577 scp = scpFree(scp);
01578
01579 leaveChroot(dbi);
01580
01581 return rc;
01582 }
01583
01584
01585
01586
01587
01588
01589
01590 struct _dbiVec sqlitevec = {
01591 0, 0, 0,
01592 sql_open,
01593 sql_close,
01594 sql_sync,
01595 sql_associate,
01596 sql_join,
01597 sql_copen,
01598 sql_cclose,
01599 sql_cdup,
01600 sql_cdel,
01601 sql_cget,
01602 sql_cpget,
01603 sql_cput,
01604 sql_ccount,
01605 sql_byteswapped,
01606 sql_stat
01607 };
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617