mirror of
https://github.com/samba-team/samba.git
synced 2025-12-16 00:23:52 +03:00
r7844: eliminate superfluous attribute tables
(This used to be commit 863beef35b)
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
4432cc73ae
commit
f1a853664c
@@ -200,10 +200,6 @@ new_dn(struct ldb_module * module,
|
||||
char * pDN,
|
||||
long long * pEID);
|
||||
|
||||
static int
|
||||
new_attr(struct ldb_module * module,
|
||||
char * pAttrName);
|
||||
|
||||
static void
|
||||
base160_sql(sqlite3_context * hContext,
|
||||
int argc,
|
||||
@@ -351,7 +347,7 @@ lsqlite3_rename(struct ldb_module * module,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Determine the eid of the DN being deleted */
|
||||
/* Determine the eid of the DN being renamed */
|
||||
QUERY_INT(lsqlite3,
|
||||
eid,
|
||||
TRUE,
|
||||
@@ -369,9 +365,12 @@ lsqlite3_rename(struct ldb_module * module,
|
||||
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
TRUE,
|
||||
"UPDATE ldb_attr_DN "
|
||||
" SET attr_value = %Q "
|
||||
" WHERE eid = %lld;",
|
||||
"UPDATE ldb_attribute_values "
|
||||
" SET attr_value = %Q, "
|
||||
" attr_value_normalized = upper(%Q) "
|
||||
" WHERE eid = %lld "
|
||||
" AND attr_name = 'DN';",
|
||||
pNewDN,
|
||||
pNewDN,
|
||||
eid);
|
||||
|
||||
@@ -389,12 +388,7 @@ static int
|
||||
lsqlite3_delete(struct ldb_module * module,
|
||||
const char * pDN)
|
||||
{
|
||||
int ret;
|
||||
int bLoop;
|
||||
long long eid;
|
||||
char * pSql;
|
||||
const char * pAttrName;
|
||||
sqlite3_stmt * pStmt;
|
||||
struct lsqlite3_private * lsqlite3 = module->private_data;
|
||||
|
||||
/* ignore ltdb specials */
|
||||
@@ -415,92 +409,11 @@ lsqlite3_delete(struct ldb_module * module,
|
||||
eid,
|
||||
TRUE,
|
||||
"SELECT eid\n"
|
||||
" FROM ldb_entry\n"
|
||||
" WHERE dn = %Q;",
|
||||
" FROM ldb_attribute_values\n"
|
||||
" WHERE attr_name = 'DN'\n"
|
||||
" AND attr_value_normalized = upper(%Q);",
|
||||
pDN);
|
||||
|
||||
/* Obtain the list of attribute names in use by this DN */
|
||||
if ((pSql = talloc_asprintf(module->ldb,
|
||||
"SELECT upper(attr_name) "
|
||||
" FROM ldb_attribute_values "
|
||||
" WHERE eid = %lld;",
|
||||
eid)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare and execute the SQL statement. Loop allows retrying on
|
||||
* certain errors, e.g. SQLITE_SCHEMA occurs if the schema changes,
|
||||
* requiring retrying the operation.
|
||||
*/
|
||||
for (bLoop = TRUE; bLoop; ) {
|
||||
/* Compile the SQL statement into sqlite virtual machine */
|
||||
if ((ret = sqlite3_prepare(lsqlite3->sqlite,
|
||||
pSql,
|
||||
-1,
|
||||
&pStmt,
|
||||
NULL)) == SQLITE_SCHEMA) {
|
||||
continue;
|
||||
} else if (ret != SQLITE_OK) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Loop through the returned rows */
|
||||
for (ret = SQLITE_ROW; ret == SQLITE_ROW; ) {
|
||||
|
||||
/* Get the next row */
|
||||
if ((ret = sqlite3_step(pStmt)) == SQLITE_ROW) {
|
||||
|
||||
/* Get the values from this row */
|
||||
pAttrName = sqlite3_column_text(pStmt, 0);
|
||||
|
||||
/*
|
||||
* Delete any entries from the specified
|
||||
* attribute table that pertain to this eid.
|
||||
*/
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
TRUE,
|
||||
"DELETE FROM ldb_attr_%q "
|
||||
" WHERE eid = %lld;",
|
||||
pAttrName, eid);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == SQLITE_SCHEMA) {
|
||||
(void) sqlite3_finalize(pStmt);
|
||||
continue;
|
||||
} else if (ret != SQLITE_DONE) {
|
||||
(void) sqlite3_finalize(pStmt);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Free the virtual machine */
|
||||
if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) {
|
||||
(void) sqlite3_finalize(pStmt);
|
||||
continue;
|
||||
} else if (ret != SQLITE_OK) {
|
||||
(void) sqlite3_finalize(pStmt);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normal condition is only one time through loop. Loop is
|
||||
* rerun in error conditions, via "continue", above.
|
||||
*/
|
||||
ret = 0;
|
||||
bLoop = FALSE;
|
||||
}
|
||||
|
||||
/* Delete the DN attribute entry */
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
TRUE,
|
||||
"DELETE FROM ldb_attr_DN "
|
||||
" WHERE eid = %lld;",
|
||||
eid);
|
||||
|
||||
/* Delete attribute/value table entries pertaining to this DN */
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
TRUE,
|
||||
@@ -579,8 +492,9 @@ lsqlite3_search_bytree(struct ldb_module * module,
|
||||
if ((ret = query_int(lsqlite3,
|
||||
&eid,
|
||||
"SELECT eid\n"
|
||||
" FROM ldb_attr_DN\n"
|
||||
" WHERE attr_value = %Q;",
|
||||
" FROM ldb_attribute_values\n"
|
||||
" WHERE attr_name = 'DN'\n"
|
||||
" AND attr_value_normalized = upper(%Q);",
|
||||
pBaseDN)) == SQLITE_DONE) {
|
||||
UNLOCK_DB(module, "rollback");
|
||||
talloc_free(hTalloc);
|
||||
@@ -917,10 +831,13 @@ lsqlite3_search(struct ldb_module * module,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* (|(objectclass=*)(dn=*)) is passed by the command line tool now instead */
|
||||
/* Handle the special case of requesting all */
|
||||
if (pExpression != NULL && *pExpression == '\0') {
|
||||
pExpression = "dn=*";
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Parse the filter expression into a tree we can work with */
|
||||
if ((pTree = ldb_parse_tree(module->ldb, pExpression)) == NULL) {
|
||||
@@ -1152,40 +1069,11 @@ initialize(struct lsqlite3_private *lsqlite3,
|
||||
"("
|
||||
" eid INTEGER REFERENCES ldb_entry,"
|
||||
" attr_name TEXT,"
|
||||
" attr_value TEXT"
|
||||
" attr_value TEXT,"
|
||||
" attr_value_normalized TEXT "
|
||||
");"
|
||||
|
||||
/*
|
||||
* There is one attribute table per searchable attribute.
|
||||
*/
|
||||
/*
|
||||
"CREATE TABLE ldb_attr_ATTRIBUTE_NAME"
|
||||
"("
|
||||
" eid INTEGER REFERENCES ldb_entry,"
|
||||
" attr_value TEXT"
|
||||
");"
|
||||
*/
|
||||
|
||||
/*
|
||||
* We pre-create the dn attribute table
|
||||
*/
|
||||
"CREATE TABLE ldb_attr_DN"
|
||||
"("
|
||||
" eid INTEGER PRIMARY KEY REFERENCES ldb_entry,"
|
||||
" attr_value TEXT"
|
||||
");"
|
||||
|
||||
|
||||
/*
|
||||
* We pre-create the objectclass attribute table
|
||||
*/
|
||||
"CREATE TABLE ldb_attr_OBJECTCLASS"
|
||||
"("
|
||||
" eid INTEGER REFERENCES ldb_entry,"
|
||||
" attr_value TEXT"
|
||||
");"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Indexes
|
||||
*/
|
||||
@@ -1195,8 +1083,6 @@ initialize(struct lsqlite3_private *lsqlite3,
|
||||
"CREATE INDEX ldb_attribute_values_eid_idx "
|
||||
" ON ldb_attribute_values (eid);"
|
||||
|
||||
"CREATE INDEX ldb_attr_DN_attr_value_idx "
|
||||
" ON ldb_attr_DN (attr_value);"
|
||||
|
||||
|
||||
/*
|
||||
@@ -1269,10 +1155,10 @@ initialize(struct lsqlite3_private *lsqlite3,
|
||||
" (0, NULL, '', '0001');"
|
||||
|
||||
/* And the root node "dn" attribute */
|
||||
"INSERT INTO ldb_attr_DN "
|
||||
" (eid, attr_value) "
|
||||
"INSERT INTO ldb_attribute_values "
|
||||
" (eid, attr_name, attr_value, attr_value_normalized) "
|
||||
" VALUES "
|
||||
" (0, '');"
|
||||
" (0, 'DN', '', '');"
|
||||
|
||||
"INSERT INTO ldb_object_classes "
|
||||
" (class_name, tree_key) "
|
||||
@@ -1387,14 +1273,12 @@ initialize(struct lsqlite3_private *lsqlite3,
|
||||
if (query_int(lsqlite3,
|
||||
&queryInt,
|
||||
"SELECT "
|
||||
" (SELECT COUNT(*) = 4"
|
||||
" (SELECT COUNT(*) = 2"
|
||||
" FROM sqlite_master "
|
||||
" WHERE type = 'table' "
|
||||
" AND name IN "
|
||||
" ("
|
||||
" 'ldb_entry', "
|
||||
" 'ldb_attr_DN', "
|
||||
" 'ldb_attr_OBJECTCLASS', "
|
||||
" 'ldb_object_classes' "
|
||||
" ) "
|
||||
" ) "
|
||||
@@ -1911,9 +1795,7 @@ parsetree_to_sql(struct ldb_module *module,
|
||||
|
||||
/*
|
||||
* For simple searches, we want to retrieve the list of EIDs that
|
||||
* match the criteria. We accomplish this by searching the
|
||||
* appropriate table, ldb_attr_<attributeName>, for the eid
|
||||
* corresponding to all matching values.
|
||||
* match the criteria.
|
||||
*/
|
||||
if (t->u.simple.value.length == 1 &&
|
||||
(*(const char *) t->u.simple.value.data) == '*') {
|
||||
@@ -1923,8 +1805,9 @@ parsetree_to_sql(struct ldb_module *module,
|
||||
* table.
|
||||
*/
|
||||
if ((p = sqlite3_mprintf(" SELECT eid\n"
|
||||
" FROM ldb_attr_%q\n",
|
||||
pAttrName)) == NULL) {
|
||||
" FROM ldb_attribute_values\n"
|
||||
" WHERE attr_name = %Q",
|
||||
pAttrName)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1942,8 +1825,9 @@ parsetree_to_sql(struct ldb_module *module,
|
||||
*/
|
||||
if ((p = sqlite3_mprintf(
|
||||
" SELECT eid\n"
|
||||
" FROM ldb_attr_OBJECTCLASS\n"
|
||||
" WHERE attr_value IN\n"
|
||||
" FROM ldb_attribute_values\n"
|
||||
" WHERE attr_name = 'OBJECTCLASS' "
|
||||
" AND attr_value_normalized IN\n"
|
||||
" (SELECT class_name\n"
|
||||
" FROM ldb_object_classes\n"
|
||||
" WHERE tree_key GLOB\n"
|
||||
@@ -1965,11 +1849,13 @@ parsetree_to_sql(struct ldb_module *module,
|
||||
} else if (strcasecmp(t->u.simple.attr, "dn") == 0) {
|
||||
pDN = ldb_dn_fold(module->ldb, t->u.simple.value.data,
|
||||
module, case_fold_attr_required);
|
||||
if ((p = sqlite3_mprintf(" SELECT eid\n"
|
||||
" FROM ldb_attr_%q\n"
|
||||
" WHERE attr_value = %Q\n",
|
||||
pAttrName,
|
||||
pDN)) == NULL) {
|
||||
if ((p = sqlite3_mprintf(
|
||||
" SELECT eid\n"
|
||||
" FROM ldb_attribute_values\n"
|
||||
" WHERE attr_name = %Q\n"
|
||||
" AND attr_value_normalized = upper(%Q)\n",
|
||||
pAttrName,
|
||||
pDN)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1981,11 +1867,13 @@ parsetree_to_sql(struct ldb_module *module,
|
||||
sqlite3_free(p);
|
||||
} else {
|
||||
/* A normal query. */
|
||||
if ((p = sqlite3_mprintf(" SELECT eid\n"
|
||||
" FROM ldb_attr_%q\n"
|
||||
" WHERE attr_value = %Q\n",
|
||||
pAttrName,
|
||||
t->u.simple.value.data)) == NULL) {
|
||||
if ((p = sqlite3_mprintf(
|
||||
" SELECT eid\n"
|
||||
" FROM ldb_attribute_values\n"
|
||||
" WHERE attr_name = %Q\n"
|
||||
" AND attr_value_normalized = upper(%Q)\n",
|
||||
pAttrName,
|
||||
t->u.simple.value.data)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2074,115 +1962,6 @@ parsetree_to_attrlist(struct ldb_module *module,
|
||||
}
|
||||
|
||||
|
||||
#ifdef NEED_TABLE_LIST
|
||||
/*
|
||||
* Use the already-generated FILTER_ATTR_TABLE to create a list of attribute
|
||||
* table names that will be used in search queries.
|
||||
*/
|
||||
static char *
|
||||
build_attr_table_list(void * hTalloc,
|
||||
struct lsqlite3_private * lsqlite3)
|
||||
{
|
||||
int ret;
|
||||
int bLoop;
|
||||
char * p;
|
||||
char * pAttrName;
|
||||
char * pTableList;
|
||||
sqlite3_stmt * pStmt;
|
||||
|
||||
/*
|
||||
* Prepare and execute the SQL statement. Loop allows retrying on
|
||||
* certain errors, e.g. SQLITE_SCHEMA occurs if the schema changes,
|
||||
* requiring retrying the operation.
|
||||
*/
|
||||
for (bLoop = TRUE; bLoop; ) {
|
||||
/* Initialize a string to which we'll append each table name */
|
||||
if ((pTableList = talloc_strdup(hTalloc, "")) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Compile the SQL statement into sqlite virtual machine */
|
||||
if ((ret = sqlite3_prepare(lsqlite3->sqlite,
|
||||
"SELECT attr_name "
|
||||
" FROM " FILTER_ATTR_TABLE ";",
|
||||
-1,
|
||||
&pStmt,
|
||||
NULL)) == SQLITE_SCHEMA) {
|
||||
continue;
|
||||
} else if (ret != SQLITE_OK) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Loop through the returned rows */
|
||||
for (ret = SQLITE_ROW; ret == SQLITE_ROW; ) {
|
||||
|
||||
/* Get the next row */
|
||||
if ((ret = sqlite3_step(pStmt)) == SQLITE_ROW) {
|
||||
|
||||
/*
|
||||
* Get value from this row and append to table
|
||||
* list
|
||||
*/
|
||||
p = discard_const_p(char,
|
||||
sqlite3_column_text(pStmt,
|
||||
0));
|
||||
|
||||
pAttrName =
|
||||
ldb_casefold(
|
||||
hTalloc,
|
||||
sqlite3_column_text(pStmt, 0));
|
||||
|
||||
/* Append it to the table list */
|
||||
if ((p = talloc_asprintf(
|
||||
hTalloc,
|
||||
"%sldb_attr_%s",
|
||||
*pTableList == '\0' ? "" : ",",
|
||||
pAttrName)) == NULL) {
|
||||
|
||||
talloc_free(pTableList);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We have a new table list */
|
||||
talloc_free(pTableList);
|
||||
pTableList = p;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == SQLITE_SCHEMA) {
|
||||
talloc_free(pTableList);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Free the virtual machine */
|
||||
if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) {
|
||||
(void) sqlite3_finalize(pStmt);
|
||||
continue;
|
||||
} else if (ret != SQLITE_OK) {
|
||||
(void) sqlite3_finalize(pStmt);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Normal condition is only one time through loop. Loop is
|
||||
* rerun in error conditions, via "continue", above.
|
||||
*/
|
||||
ret = 0;
|
||||
bLoop = FALSE;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
talloc_free(pTableList);
|
||||
pTableList = NULL;
|
||||
}
|
||||
|
||||
return pTableList;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Issue a series of SQL statements to implement the ADD/MODIFY/DELETE
|
||||
* requests in the ldb_message
|
||||
@@ -2212,37 +1991,26 @@ msg_to_sql(struct ldb_module * module,
|
||||
pAttrName = ldb_casefold((struct ldb_context *) module,
|
||||
el->name);
|
||||
|
||||
if (flags == LDB_FLAG_MOD_ADD) {
|
||||
/* Create the attribute table if it doesn't exist */
|
||||
if (new_attr(module, pAttrName) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* For each value of the specified attribute name... */
|
||||
for (j = 0; j < el->num_values; j++) {
|
||||
|
||||
/* ... bind the attribute value, if necessary */
|
||||
switch (flags) {
|
||||
case LDB_FLAG_MOD_ADD:
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
FALSE,
|
||||
"INSERT INTO ldb_attr_%q\n"
|
||||
" (eid, attr_value)\n"
|
||||
" VALUES\n"
|
||||
" (%lld, %Q);",
|
||||
pAttrName,
|
||||
eid, el->values[j].data);
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
FALSE,
|
||||
"INSERT INTO ldb_attribute_values"
|
||||
" (eid, attr_name, attr_value)"
|
||||
" VALUES "
|
||||
" (%lld, %Q, %Q);",
|
||||
eid,
|
||||
el->name,
|
||||
el->values[j].data);
|
||||
|
||||
QUERY_NOROWS(
|
||||
lsqlite3,
|
||||
FALSE,
|
||||
"INSERT INTO ldb_attribute_values\n"
|
||||
" (eid,\n"
|
||||
" attr_name,\n"
|
||||
" attr_value,\n"
|
||||
" attr_value_normalized)\n"
|
||||
" VALUES\n"
|
||||
" (%lld, %Q, %Q, upper(%Q));",
|
||||
eid,
|
||||
pAttrName,
|
||||
el->values[j].data, /* FIX ME */
|
||||
el->values[j].data);
|
||||
|
||||
/* Is this a special "objectclass"? */
|
||||
if (strcasecmp(pAttrName,
|
||||
@@ -2265,44 +2033,34 @@ msg_to_sql(struct ldb_module * module,
|
||||
break;
|
||||
|
||||
case LDB_FLAG_MOD_REPLACE:
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
FALSE,
|
||||
"UPDATE ldb_attr_%q\n"
|
||||
" SET attr_value = %Q\n"
|
||||
" WHERE eid = %lld;",
|
||||
pAttrName,
|
||||
el->values[j].data,
|
||||
eid);
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
FALSE,
|
||||
"UPDATE ldb_attribute_values "
|
||||
" SET attr_value = %Q "
|
||||
" WHERE eid = %lld "
|
||||
" AND attr_name = %Q;",
|
||||
el->values[j].data,
|
||||
eid,
|
||||
el->name);
|
||||
QUERY_NOROWS(
|
||||
lsqlite3,
|
||||
FALSE,
|
||||
"UPDATE ldb_attribute_values\n"
|
||||
" SET attr_value = %Q,\n"
|
||||
" attr_value_normalized =\n"
|
||||
" upper(%Q)\n"
|
||||
" WHERE eid = %lld\n"
|
||||
" AND attr_name = %Q;",
|
||||
el->values[j].data, /* FIX ME */
|
||||
el->values[j].data,
|
||||
eid,
|
||||
pAttrName);
|
||||
break;
|
||||
|
||||
case LDB_FLAG_MOD_DELETE:
|
||||
/* No additional parameters to this query */
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
FALSE,
|
||||
"DELETE FROM ldb_attr_%q\n"
|
||||
" WHERE eid = %lld\n"
|
||||
" AND attr_value = %Q;",
|
||||
pAttrName,
|
||||
eid,
|
||||
el->values[j].data);
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
FALSE,
|
||||
"DELETE FROM ldb_attribute_values"
|
||||
" WHERE eid = %lld "
|
||||
" AND attr_name = %Q "
|
||||
" AND attr_value = %Q;",
|
||||
eid,
|
||||
el->name,
|
||||
el->values[j].data);
|
||||
QUERY_NOROWS(
|
||||
lsqlite3,
|
||||
FALSE,
|
||||
"DELETE FROM ldb_attribute_values"
|
||||
" WHERE eid = %lld "
|
||||
" AND attr_name = %Q "
|
||||
" AND attr_value_normalized =\n"
|
||||
" upper(%Q);",
|
||||
eid,
|
||||
el->name,
|
||||
el->values[j].data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2456,12 +2214,17 @@ new_dn(struct ldb_module * module,
|
||||
/* Also add DN attribute */
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
FALSE,
|
||||
"INSERT %s INTO ldb_attr_DN\n"
|
||||
" (eid, attr_value) "
|
||||
"INSERT %s INTO ldb_attribute_values\n"
|
||||
" (eid,\n"
|
||||
" attr_name,\n"
|
||||
" attr_value,\n"
|
||||
" attr_value_normalized) "
|
||||
" VALUES "
|
||||
" (%lld, %Q);",
|
||||
" (%lld, 'DN', %Q, upper(%Q));",
|
||||
nComponent == 0 ? "" : "OR IGNORE",
|
||||
eid, pPartialDN);
|
||||
eid,
|
||||
pPartialDN, /* FIX ME */
|
||||
pPartialDN);
|
||||
}
|
||||
|
||||
if (lsqlite3_debug & SQLITE3_DEBUG_NEWDN) {
|
||||
@@ -2479,60 +2242,6 @@ new_dn(struct ldb_module * module,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
new_attr(struct ldb_module * module,
|
||||
char * pAttrName)
|
||||
{
|
||||
long long bExists;
|
||||
struct lsqlite3_private * lsqlite3 = module->private_data;
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* pAttrName is assumed to already be case-folded here!
|
||||
*/
|
||||
|
||||
/* See if the table already exists */
|
||||
QUERY_INT(lsqlite3,
|
||||
bExists,
|
||||
FALSE,
|
||||
"SELECT COUNT(*) <> 0\n"
|
||||
" FROM sqlite_master\n"
|
||||
" WHERE type = 'table'\n"
|
||||
" AND tbl_name = 'ldb_attr_%q';",
|
||||
pAttrName);
|
||||
|
||||
/* Did it exist? */
|
||||
if (! bExists) {
|
||||
/* Nope. Create the table */
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
FALSE,
|
||||
"CREATE TABLE ldb_attr_%q\n"
|
||||
"(\n"
|
||||
" eid INTEGER REFERENCES ldb_entry,\n"
|
||||
" attr_value TEXT\n"
|
||||
");",
|
||||
pAttrName);
|
||||
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
FALSE,
|
||||
"CREATE INDEX ldb_attr_%q_eid_idx\n"
|
||||
" ON ldb_attr_%q (eid);",
|
||||
pAttrName,
|
||||
pAttrName);
|
||||
|
||||
QUERY_NOROWS(lsqlite3,
|
||||
FALSE,
|
||||
"CREATE INDEX ldb_attr_%q_attr_value_idx "
|
||||
" ON ldb_attr_%q (attr_value);",
|
||||
pAttrName,
|
||||
pAttrName);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned char base160tab[161] = {
|
||||
48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 , /* 0-9 */
|
||||
58 ,59 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 , /* : ; A-H */
|
||||
|
||||
Reference in New Issue
Block a user