⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldb_sqlite3.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (attr == NULL) return NULL;		a = ldb_schema_attribute_by_name(module->ldb, attr);		/* Get a canonicalised copy of the data */		a->syntax->canonicalise_fn(module->ldb, mem_ctx, &(t->u.equality.value), &value);		if (value.data == NULL) {			return NULL;		}		return lsqlite3_tprintf(mem_ctx,					"SELECT eid FROM ldb_attribute_values "					"WHERE norm_attr_name = '%q' "					"AND ldap_compare(norm_attr_value, '~%', 'q', '%q') ",					attr,					value.data,					attr);			case LDB_OP_EXTENDED:#warning  "work out how to handle bitops"		return NULL;	default:		break;	};	/* should never occur */	abort();	return NULL;}/* * query_int() * * This function is used for the common case of queries that return a single * integer value. * * NOTE: If more than one value is returned by the query, all but the first * one will be ignored. */static intquery_int(const struct lsqlite3_private * lsqlite3,          long long * pRet,          const char * pSql,          ...){        int             ret;        int             bLoop;        char *          p;        sqlite3_stmt *  pStmt;        va_list         args;                /* Begin access to variable argument list */        va_start(args, pSql);                /* Format the query */        if ((p = sqlite3_vmprintf(pSql, args)) == NULL) {                return SQLITE_NOMEM;        }                /*         * 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,                                           p,                                           -1,                                           &pStmt,                                           NULL)) == SQLITE_SCHEMA) {                        if (stmtGetEID != NULL) {                                sqlite3_finalize(stmtGetEID);                                stmtGetEID = NULL;                        }                        continue;                } else if (ret != SQLITE_OK) {                        break;                }                                /* 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) {                        (void) sqlite3_finalize(pStmt);                        break;                }                                /* Get the value to be returned */                *pRet = sqlite3_column_int64(pStmt, 0);                                /* Free the virtual machine */                if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) {                        if (stmtGetEID != NULL) {                                sqlite3_finalize(stmtGetEID);                                stmtGetEID = NULL;                        }                        continue;                } else if (ret != SQLITE_OK) {                        (void) sqlite3_finalize(pStmt);                        break;                }                                /*                 * Normal condition is only one time through loop.  Loop is                 * rerun in error conditions, via "continue", above.                 */                bLoop = FALSE;        }                /* All done with variable argument list */        va_end(args);                /* Free the memory we allocated for our query string */        sqlite3_free(p);                return ret;}/* * This is a bad hack to support ldap style comparisons whithin sqlite. * val is the attribute in the row currently under test * func is the desired test "<=" ">=" "~" ":" * cmp is the value to compare against (eg: "test") * attr is the attribute name the value of which we want to test */static void lsqlite3_compare(sqlite3_context *ctx, int argc,					sqlite3_value **argv){	struct ldb_context *ldb = (struct ldb_context *)sqlite3_user_data(ctx);	const char *val = (const char *)sqlite3_value_text(argv[0]);	const char *func = (const char *)sqlite3_value_text(argv[1]);	const char *cmp = (const char *)sqlite3_value_text(argv[2]);	const char *attr = (const char *)sqlite3_value_text(argv[3]);	const struct ldb_schema_attribute *a;	struct ldb_val valX;	struct ldb_val valY;	int ret;	switch (func[0]) {	/* greater */	case '>': /* >= */		a = ldb_schema_attribute_by_name(ldb, attr);		valX.data = (void *)cmp;		valX.length = strlen(cmp);		valY.data = (void *)val;		valY.length = strlen(val);		ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX);		if (ret >= 0)			sqlite3_result_int(ctx, 1);		else			sqlite3_result_int(ctx, 0);		return;	/* lesser */	case '<': /* <= */		a = ldb_schema_attribute_by_name(ldb, attr);		valX.data = (void *)cmp;		valX.length = strlen(cmp);		valY.data = (void *)val;		valY.length = strlen(val);		ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX);		if (ret <= 0)			sqlite3_result_int(ctx, 1);		else			sqlite3_result_int(ctx, 0);		return;	/* approx */	case '~':		/* TODO */		sqlite3_result_int(ctx, 0);		return;	/* bitops */	case ':':		/* TODO */		sqlite3_result_int(ctx, 0);		return;	default:		break;	}	sqlite3_result_error(ctx, "Value must start with a special operation char (<>~:)!", -1);	return;}/* rename a record */static int lsqlite3_safe_rollback(sqlite3 *sqlite){	char *errmsg;	int ret;	/* execute */	ret = sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, &errmsg);	if (ret != SQLITE_OK) {		if (errmsg) {			printf("lsqlite3_safe_rollback: Error: %s\n", errmsg);			free(errmsg);		}		return -1;	}        return 0;}/* return an eid as result */static int lsqlite3_eid_callback(void *result, int col_num, char **cols, char **names){	long long *eid = (long long *)result;	if (col_num != 1) return SQLITE_ABORT;	if (strcasecmp(names[0], "eid") != 0) return SQLITE_ABORT;	*eid = atoll(cols[0]);	return SQLITE_OK;}/* * add a single set of ldap message values to a ldb_message */static int lsqlite3_search_callback(void *result, int col_num, char **cols, char **names){	struct ldb_handle *handle = talloc_get_type(result, struct ldb_handle);	struct lsql_context *ac = talloc_get_type(handle->private_data, struct lsql_context);	struct ldb_message *msg;	long long eid;	int i;	/* eid, dn, attr_name, attr_value */	if (col_num != 4)		return SQLITE_ABORT;	eid = atoll(cols[0]);	if (eid != ac->current_eid) { /* here begin a new entry */		/* call the async callback for the last entry		 * except the first time */		if (ac->current_eid != 0) {			ac->ares->message = ldb_msg_canonicalize(ac->module->ldb, ac->ares->message);			if (ac->ares->message == NULL)				return SQLITE_ABORT;						handle->status = ac->callback(ac->module->ldb, ac->context, ac->ares);			if (handle->status != LDB_SUCCESS)				return SQLITE_ABORT;		}		/* start over */		ac->ares = talloc_zero(ac, struct ldb_reply);		if (!ac->ares)			return SQLITE_ABORT;		ac->ares->message = ldb_msg_new(ac->ares);		if (!ac->ares->message)			return SQLITE_ABORT;		ac->ares->type = LDB_REPLY_ENTRY;		ac->current_eid = eid;	}	msg = ac->ares->message;	if (msg->dn == NULL) {		msg->dn = ldb_dn_new(msg, ac->module->ldb, cols[1]);		if (msg->dn == NULL)			return SQLITE_ABORT;	}	if (ac->attrs) {		int found = 0;		for (i = 0; ac->attrs[i]; i++) {			if (strcasecmp(cols[2], ac->attrs[i]) == 0) {				found = 1;				break;			}		}		if (!found) return SQLITE_OK;	}	if (ldb_msg_add_string(msg, cols[2], cols[3]) != 0) {		return SQLITE_ABORT;	}	return SQLITE_OK;}/* * lsqlite3_get_eid() * lsqlite3_get_eid_ndn() * * These functions are used for the very common case of retrieving an EID value * given a (normalized) DN. */static long long lsqlite3_get_eid_ndn(sqlite3 *sqlite, void *mem_ctx, const char *norm_dn){	char *errmsg;	char *query;	long long eid = -1;	long long ret;	/* get object eid */	query = lsqlite3_tprintf(mem_ctx, "SELECT eid "					  "FROM ldb_entry "					  "WHERE norm_dn = '%q';", norm_dn);	if (query == NULL) return -1;	ret = sqlite3_exec(sqlite, query, lsqlite3_eid_callback, &eid, &errmsg);	if (ret != SQLITE_OK) {		if (errmsg) {			printf("lsqlite3_get_eid: Fatal Error: %s\n", errmsg);			free(errmsg);		}		return -1;	}	return eid;}static long long lsqlite3_get_eid(struct ldb_module *module, struct ldb_dn *dn){	TALLOC_CTX *local_ctx;	struct lsqlite3_private *lsqlite3 = module->private_data;	long long eid = -1;	char *cdn;	/* ignore ltdb specials */	if (ldb_dn_is_special(dn)) {		return -1;	}	/* create a local ctx */	local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_get_eid local context");	if (local_ctx == NULL) {		return -1;	}	cdn = ldb_dn_alloc_casefold(local_ctx, dn);	if (!cdn) goto done;	eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, local_ctx, cdn);done:	talloc_free(local_ctx);	return eid;}/* * Interface functions referenced by lsqlite3_ops *//* search for matching records, by tree */int lsql_search(struct ldb_module *module, struct ldb_request *req){	struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private);	struct lsql_context *lsql_ac;	char *norm_basedn;	char *sqlfilter;	char *errmsg;	char *query = NULL;        int ret;	req->handle = init_handle(lsqlite3, module, req);	if (req->handle == NULL) {		return LDB_ERR_OPERATIONS_ERROR;	}	lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context);	if ((( ! ldb_dn_is_valid(req->op.search.base)) || ldb_dn_is_null(req->op.search.base)) &&	    (req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL))		return LDB_ERR_OPERATIONS_ERROR;	if (req->op.search.base) {		norm_basedn = ldb_dn_alloc_casefold(lsql_ac, req->op.search.base);		if (norm_basedn == NULL) {			ret = LDB_ERR_INVALID_DN_SYNTAX;			goto failed;		}	} else norm_basedn = talloc_strdup(lsql_ac, "");        /* Convert filter into a series of SQL conditions (constraints) */	sqlfilter = parsetree_to_sql(module, lsql_ac, req->op.search.tree);                switch(req->op.search.scope) {        case LDB_SCOPE_DEFAULT:        case LDB_SCOPE_SUBTREE:		if (*norm_basedn != '\0') {			query = lsqlite3_tprintf(lsql_ac,				"SELECT entry.eid,\n"				"       entry.dn,\n"				"       av.attr_name,\n"				"       av.attr_value\n"				"  FROM ldb_entry AS entry\n"				"  LEFT OUTER JOIN ldb_attribute_values AS av\n"				"    ON av.eid = entry.eid\n"				"  WHERE entry.eid IN\n"				"    (SELECT DISTINCT ldb_entry.eid\n"				"       FROM ldb_entry\n"				"       WHERE (ldb_entry.norm_dn GLOB('*,%q')\n"				"       OR ldb_entry.norm_dn = '%q')\n"				"       AND ldb_entry.eid IN\n"				"         (%s)\n"				"    )\n"				"  ORDER BY entry.eid ASC;",				norm_basedn,				norm_basedn,				sqlfilter);		} else {			query = lsqlite3_tprintf(lsql_ac,				"SELECT entry.eid,\n"				"       entry.dn,\n"				"       av.attr_name,\n"				"       av.attr_value\n"				"  FROM ldb_entry AS entry\n"				"  LEFT OUTER JOIN ldb_attribute_values AS av\n"				"    ON av.eid = entry.eid\n"				"  WHERE entry.eid IN\n"				"    (SELECT DISTINCT ldb_entry.eid\n"				"       FROM ldb_entry\n"				"       WHERE ldb_entry.eid IN\n"				"         (%s)\n"				"    )\n"				"  ORDER BY entry.eid ASC;",				sqlfilter);		}		break;                        case LDB_SCOPE_BASE:                query = lsqlite3_tprintf(lsql_ac,                        "SELECT entry.eid,\n"                        "       entry.dn,\n"                        "       av.attr_name,\n"                        "       av.attr_value\n"                        "  FROM ldb_entry AS entry\n"                        "  LEFT OUTER JOIN ldb_attribute_values AS av\n"                        "    ON av.eid = entry.eid\n"                        "  WHERE entry.eid IN\n"                        "    (SELECT DISTINCT ldb_entry.eid\n"                        "       FROM ldb_entry\n"                        "       WHERE ldb_entry.norm_dn = '%q'\n"                        "         AND ldb_entry.eid IN\n"			"           (%s)\n"                        "    )\n"                        "  ORDER BY entry.eid ASC;",			norm_basedn,                        sqlfilter);                break;                        case LDB_SCOPE_ONELEVEL:                query = lsqlite3_tprintf(lsql_ac,                        "SELECT entry.eid,\n"                        "       entry.dn,\n"                        "       av.attr_name,\n"                        "       av.attr_value\n"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -