1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-04 08:22:08 +03:00

r7897: work in progress

(This used to be commit 8e1431efcf)
This commit is contained in:
Derrell Lipman
2005-06-25 03:43:33 +00:00
committed by Gerald (Jerry) Carter
parent 1af480a32d
commit 1603fd9466
3 changed files with 224 additions and 103 deletions

View File

@ -84,6 +84,16 @@
} \
} while (0)
#define GET_EID(lsqlite3, result_var, bRollbackOnError, pDN) \
do { \
if (getEID(lsqlite3, &result_var, pDN) != 0) { \
if (bRollbackOnError) { \
UNLOCK_DB(module, "rollback"); \
} \
return -1; \
} \
} while (0)
#define SQLITE3_DEBUG_QUERY (1 << 0)
#define SQLITE3_DEBUG_INIT (1 << 1)
@ -95,6 +105,7 @@
* Static variables
*/
static int lsqlite3_debug = FALSE;
sqlite3_stmt * stmtGetEID = NULL;
/*
* Forward declarations
@ -161,6 +172,11 @@ query_int(const struct lsqlite3_private * lsqlite3,
const char * pSql,
...);
static int
getEID(const struct lsqlite3_private * lsqlite3,
long long * pRet,
const char * pNormalizedDN);
static int case_fold_attr_required(void * hUserData,
char *attr);
@ -336,10 +352,10 @@ lsqlite3_rename(struct ldb_module * module,
}
/* Case-fold each of the DNs */
pOldNormalizedDN = ldb_dn_fold(module->ldb, pOldDN,
module, case_fold_attr_required);
pNewNormalizedDN = ldb_dn_fold(module->ldb, pNewDN,
module, case_fold_attr_required);
pOldNormalizedDN =
ldb_dn_fold(module->ldb, pOldDN, module, case_fold_attr_required);
pNewNormalizedDN =
ldb_dn_fold(module->ldb, pNewDN, module, case_fold_attr_required);
/* Begin a transaction */
if (LOCK_DB(module, "transaction") < 0) {
@ -347,13 +363,7 @@ lsqlite3_rename(struct ldb_module * module,
}
/* Determine the eid of the DN being renamed */
QUERY_INT(lsqlite3,
eid,
TRUE,
"SELECT eid\n"
" FROM ldb_entry\n"
" WHERE normalized_dn = %Q;",
pOldNormalizedDN);
GET_EID(lsqlite3, eid, TRUE, pOldNormalizedDN);
QUERY_NOROWS(lsqlite3,
TRUE,
@ -403,17 +413,11 @@ lsqlite3_delete(struct ldb_module * module,
}
/* Case-fold the DNs */
pNormalizedDN = ldb_dn_fold(module->ldb, pDN, module, case_fold_attr_required);
pNormalizedDN =
ldb_dn_fold(module->ldb, pDN, module, case_fold_attr_required);
/* Determine the eid of the DN being deleted */
QUERY_INT(lsqlite3,
eid,
TRUE,
"SELECT eid\n"
" FROM ldb_attribute_values\n"
" WHERE attr_name = 'DN'\n"
" AND attr_value_normalized = %Q;",
pNormalizedDN);
GET_EID(lsqlite3, eid, TRUE, pNormalizedDN);
/* Delete attribute/value table entries pertaining to this DN */
QUERY_NOROWS(lsqlite3,
@ -470,26 +474,26 @@ lsqlite3_search_bytree(struct ldb_module * module,
}
/* Case-fold the base DN */
if ((pNormalizedBaseDN = ldb_dn_fold(hTalloc, pBaseDN?pBaseDN:"",
module, case_fold_attr_required)) == NULL) {
if ((pNormalizedBaseDN =
ldb_dn_fold(hTalloc,
pBaseDN == NULL ? "" : pBaseDN,
module,
case_fold_attr_required)) == NULL) {
talloc_free(hTalloc);
return -1;
}
/* Begin a transaction */
if (LOCK_DB(module, "transaction") < 0) {
talloc_free(hTalloc);
return -1;
}
/*
* Obtain the eid of the base DN
*/
if ((ret = query_int(lsqlite3,
&eid,
"SELECT eid\n"
" FROM ldb_entry\n"
" WHERE normalized_dn = %Q;",
pNormalizedBaseDN)) == SQLITE_DONE) {
if ((ret = getEID(lsqlite3, &eid, pNormalizedBaseDN)) == SQLITE_DONE) {
UNLOCK_DB(module, "rollback");
talloc_free(hTalloc);
return 0;
@ -685,9 +689,15 @@ lsqlite3_search_bytree(struct ldb_module * module,
-1,
&pStmt,
NULL)) == SQLITE_SCHEMA) {
if (stmtGetEID != NULL) {
sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
}
if (pppRes != NULL && *pppRes != NULL) {
talloc_free(*pppRes);
}
continue;
} else if (ret != SQLITE_OK) {
ret = -1;
@ -730,6 +740,11 @@ lsqlite3_search_bytree(struct ldb_module * module,
}
if (ret == SQLITE_SCHEMA) {
if (stmtGetEID != NULL) {
sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
}
(void) sqlite3_finalize(pStmt);
if (pppRes != NULL && *pppRes != NULL) {
talloc_free(*pppRes);
@ -743,7 +758,11 @@ lsqlite3_search_bytree(struct ldb_module * module,
/* Free the virtual machine */
if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) {
(void) sqlite3_finalize(pStmt);
if (stmtGetEID != NULL) {
sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
}
if (pppRes != NULL && *pppRes != NULL) {
talloc_free(*pppRes);
}
@ -916,13 +935,7 @@ lsqlite3_modify(struct ldb_module * module,
module, case_fold_attr_required);
/* Determine the eid of the DN being deleted */
QUERY_INT(lsqlite3,
eid,
TRUE,
"SELECT eid\n"
" FROM ldb_entry\n"
" WHERE normalized_dn = %Q;",
pNormalizedDN);
GET_EID(lsqlite3, eid, TRUE, pNormalizedDN);
/* Apply the message attributes */
if (msg_to_sql(module, msg, eid, TRUE) != 0) {
@ -1068,6 +1081,9 @@ initialize(struct lsqlite3_private *lsqlite3,
"CREATE INDEX ldb_attribute_values_eid_idx "
" ON ldb_attribute_values (eid);"
"CREATE INDEX ldb_attribute_values_name_value_idx "
" ON ldb_attribute_values (attr_name, attr_value_normalized);"
/*
@ -1351,7 +1367,7 @@ query_norows(const struct lsqlite3_private *lsqlite3,
char * p;
sqlite3_stmt * pStmt;
va_list args;
double t0;
double t0 = 0;
double t1;
struct timeval tv;
struct timezone tz;
@ -1382,6 +1398,10 @@ query_norows(const struct lsqlite3_private *lsqlite3,
-1,
&pStmt,
NULL)) == SQLITE_SCHEMA) {
if (stmtGetEID != NULL) {
sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
}
continue;
} else if (ret != SQLITE_OK) {
ret = -1;
@ -1390,6 +1410,10 @@ query_norows(const struct lsqlite3_private *lsqlite3,
/* No rows expected, so just step through machine code once */
if ((ret = sqlite3_step(pStmt)) == SQLITE_SCHEMA) {
if (stmtGetEID != NULL) {
sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
}
(void) sqlite3_finalize(pStmt);
continue;
} else if (ret != SQLITE_DONE) {
@ -1400,7 +1424,10 @@ query_norows(const struct lsqlite3_private *lsqlite3,
/* Free the virtual machine */
if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) {
(void) sqlite3_finalize(pStmt);
if (stmtGetEID != NULL) {
sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
}
continue;
} else if (ret != SQLITE_OK) {
(void) sqlite3_finalize(pStmt);
@ -1454,7 +1481,7 @@ query_int(const struct lsqlite3_private * lsqlite3,
char * p;
sqlite3_stmt * pStmt;
va_list args;
double t0;
double t0 = 0;
double t1;
struct timeval tv;
struct timezone tz;
@ -1489,6 +1516,10 @@ query_int(const struct lsqlite3_private * lsqlite3,
-1,
&pStmt,
NULL)) == SQLITE_SCHEMA) {
if (stmtGetEID != NULL) {
sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
}
continue;
} else if (ret != SQLITE_OK) {
break;
@ -1496,6 +1527,10 @@ query_int(const struct lsqlite3_private * lsqlite3,
/* One row expected */
if ((ret = sqlite3_step(pStmt)) == SQLITE_SCHEMA) {
if (stmtGetEID != NULL) {
sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
}
(void) sqlite3_finalize(pStmt);
continue;
} else if (ret != SQLITE_ROW) {
@ -1508,7 +1543,10 @@ query_int(const struct lsqlite3_private * lsqlite3,
/* Free the virtual machine */
if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) {
(void) sqlite3_finalize(pStmt);
if (stmtGetEID != NULL) {
sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
}
continue;
} else if (ret != SQLITE_OK) {
(void) sqlite3_finalize(pStmt);
@ -1541,6 +1579,92 @@ query_int(const struct lsqlite3_private * lsqlite3,
}
/*
* getEID()
*
* This function is used for the very common case of retrieving an EID value
* given a normalized DN.
*
* NOTE: If more than one value is returned by the query, all but the first
* one will be ignored.
*/
static int
getEID(const struct lsqlite3_private * lsqlite3,
long long * pRet,
const char * pNormalizedDN)
{
int ret;
int bLoop;
const char * query =
"SELECT eid\n"
" FROM ldb_attribute_values\n"
" WHERE attr_name = 'DN'\n"
" AND attr_value_normalized = :dn;";
/*
* 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 */
ret = SQLITE_OK;
if (stmtGetEID == NULL &&
(ret = sqlite3_prepare(lsqlite3->sqlite,
query,
-1,
&stmtGetEID,
NULL)) == SQLITE_SCHEMA) {
continue;
} else if (ret != SQLITE_OK) {
break;
}
/* Bind our parameter */
if ((ret = sqlite3_bind_text(stmtGetEID,
1,
pNormalizedDN,
-1,
SQLITE_STATIC)) != SQLITE_OK) {
break;
}
/* One row expected */
if ((ret = sqlite3_step(stmtGetEID)) == SQLITE_SCHEMA) {
(void) sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
continue;
} else if (ret != SQLITE_ROW) {
(void) sqlite3_reset(stmtGetEID);
break;
}
/* Get the value to be returned */
*pRet = sqlite3_column_int64(stmtGetEID, 0);
/* Free the virtual machine */
if ((ret = sqlite3_reset(stmtGetEID)) == SQLITE_SCHEMA) {
(void) sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
continue;
} else if (ret != SQLITE_OK) {
(void) sqlite3_finalize(stmtGetEID);
stmtGetEID = NULL;
break;
}
/*
* Normal condition is only one time through loop. Loop is
* rerun in error conditions, via "continue", above.
*/
bLoop = FALSE;
}
return ret;
}
/*
callback function used in call to ldb_dn_fold() for determining whether an
attribute type requires case folding.
@ -2072,8 +2196,9 @@ new_dn(struct ldb_module * module,
char * pDN,
long long * pEID)
{
int nComponent;
int ret;
int bFirst;
int nComponent;
char * p;
char * pPartialDN;
char * pPartialNormalizedDN;
@ -2159,7 +2284,10 @@ new_dn(struct ldb_module * module,
/* Save the new partial DN */
pPartialDN = p;
pPartialNormalizedDN = ldb_dn_fold(pPartialDN, p, module, case_fold_attr_required);
pPartialNormalizedDN = ldb_dn_fold(pPartialDN,
p,
module,
case_fold_attr_required);
if (lsqlite3_debug & SQLITE3_DEBUG_NEWDN) {
gettimeofday(&tv, NULL);
@ -2171,62 +2299,60 @@ new_dn(struct ldb_module * module,
/*
* Ensure that an entry is in the ldb_entry table for this
* component. Any component other than the last one
* (component 0) may already exist. It is an error if
* component 0 (the full DN requested to be be inserted)
* already exists.
* component.
*/
QUERY_NOROWS(lsqlite3,
FALSE,
"INSERT %s INTO ldb_entry\n"
" (peid, dn, normalized_dn)\n"
" VALUES\n"
" (%lld, %Q, %Q);",
nComponent == 0 ? "" : "OR IGNORE",
eid, pPartialDN, pPartialNormalizedDN);
if ((ret = getEID(lsqlite3,
&eid,
pPartialNormalizedDN)) == SQLITE_DONE) {
QUERY_NOROWS(lsqlite3,
FALSE,
"INSERT INTO ldb_entry\n"
" (peid, dn, normalized_dn)\n"
" VALUES\n"
" (%lld, %Q, %Q);",
eid, pPartialDN, pPartialNormalizedDN);
if (lsqlite3_debug & SQLITE3_DEBUG_NEWDN) {
gettimeofday(&tv, NULL);
t1 = ((double) tv.tv_sec +
((double) tv.tv_usec / 1000000.0));
printf("%1.6lf loc 5\n", t1 - t0);
t0 = t1;
}
/* Get the EID of the just inserted row */
eid = sqlite3_last_insert_rowid(lsqlite3->sqlite);
if (lsqlite3_debug & SQLITE3_DEBUG_NEWDN) {
gettimeofday(&tv, NULL);
t1 = ((double) tv.tv_sec +
((double) tv.tv_usec / 1000000.0));
printf("%1.6lf loc 8\n", t1 - t0);
t0 = t1;
}
/* Also add DN attribute */
QUERY_NOROWS(lsqlite3,
FALSE,
"INSERT INTO ldb_attribute_values\n"
" (eid,\n"
" attr_name,\n"
" attr_value,\n"
" attr_value_normalized) "
" VALUES "
" (%lld, 'DN', %Q, %Q);",
eid,
pPartialDN, /* FIX ME */
pPartialNormalizedDN);
} else if (ret != SQLITE_OK) {
UNLOCK_DB(module, "rollback");
return -1;
}
/* Save the parent EID */
peid = eid;
if (lsqlite3_debug & SQLITE3_DEBUG_NEWDN) {
gettimeofday(&tv, NULL);
t1 = ((double) tv.tv_sec +
((double) tv.tv_usec / 1000000.0));
printf("%1.6lf loc 5\n", t1 - t0);
t0 = t1;
}
/* Get the EID of the just inserted row */
QUERY_INT(lsqlite3,
eid,
FALSE,
"SELECT eid "
" FROM ldb_entry "
" WHERE normalized_dn = %Q;",
pPartialNormalizedDN);
if (lsqlite3_debug & SQLITE3_DEBUG_NEWDN) {
gettimeofday(&tv, NULL);
t1 = ((double) tv.tv_sec +
((double) tv.tv_usec / 1000000.0));
printf("%1.6lf loc 8\n", t1 - t0);
t0 = t1;
}
/* Also add DN attribute */
QUERY_NOROWS(lsqlite3,
FALSE,
"INSERT %s INTO ldb_attribute_values\n"
" (eid,\n"
" attr_name,\n"
" attr_value,\n"
" attr_value_normalized) "
" VALUES "
" (%lld, 'DN', %Q, %Q);",
nComponent == 0 ? "" : "OR IGNORE",
eid,
pPartialDN, /* FIX ME */
pPartialNormalizedDN);
}
if (lsqlite3_debug & SQLITE3_DEBUG_NEWDN) {