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

📄 ldb_sqlite3.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 4 页
字号:
	query = lsqlite3_tprintf(lsql_ac,				 "UPDATE ldb_entry SET dn = '%q', norm_dn = '%q' "				 "WHERE norm_dn = '%q';",				 new_dn, new_cdn, old_cdn);	if (query == NULL) {		goto done;	}	/* execute */	ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg);	if (ret != SQLITE_OK) {		if (errmsg) {			ldb_set_errstring(module->ldb, errmsg);			free(errmsg);		}		ret = LDB_ERR_OPERATIONS_ERROR;		goto done;	}	if (lsql_ac->callback) {		ret = lsql_ac->callback(module->ldb, lsql_ac->context, NULL);	}done:	req->handle->state = LDB_ASYNC_DONE;	return ret;}static int lsql_start_trans(struct ldb_module * module){	int ret;	char *errmsg;	struct lsqlite3_private *   lsqlite3 = module->private_data;	if (lsqlite3->trans_count == 0) {		ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN IMMEDIATE;", NULL, NULL, &errmsg);		if (ret != SQLITE_OK) {			if (errmsg) {				printf("lsqlite3_start_trans: error: %s\n", errmsg);				free(errmsg);			}			return -1;		}	};	lsqlite3->trans_count++;	return 0;}static int lsql_end_trans(struct ldb_module *module){	int ret;	char *errmsg;	struct lsqlite3_private *lsqlite3 = module->private_data;	if (lsqlite3->trans_count > 0) {		lsqlite3->trans_count--;	} else return -1;	if (lsqlite3->trans_count == 0) {		ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg);		if (ret != SQLITE_OK) {			if (errmsg) {				printf("lsqlite3_end_trans: error: %s\n", errmsg);				free(errmsg);			}			return -1;		}	}        return 0;}static int lsql_del_trans(struct ldb_module *module){	struct lsqlite3_private *lsqlite3 = module->private_data;	if (lsqlite3->trans_count > 0) {		lsqlite3->trans_count--;	} else return -1;	if (lsqlite3->trans_count == 0) {		return lsqlite3_safe_rollback(lsqlite3->sqlite);	}	return -1;}static int destructor(struct lsqlite3_private *lsqlite3){        	if (lsqlite3->sqlite) {		sqlite3_close(lsqlite3->sqlite);	}	return 0;}static int lsql_request(struct ldb_module *module, struct ldb_request *req){	return LDB_ERR_OPERATIONS_ERROR;}static int lsql_wait(struct ldb_handle *handle, enum ldb_wait_type type){	return handle->status;}/* * Table of operations for the sqlite3 backend */static const struct ldb_module_ops lsqlite3_ops = {	.name              = "sqlite",	.search            = lsql_search,	.add               = lsql_add,        .modify            = lsql_modify,        .del               = lsql_delete,        .rename            = lsql_rename,	.request           = lsql_request,	.start_transaction = lsql_start_trans,	.end_transaction   = lsql_end_trans,	.del_transaction   = lsql_del_trans,	.wait              = lsql_wait,};/* * Static functions */static int initialize(struct lsqlite3_private *lsqlite3,		      struct ldb_context *ldb, const char *url, int flags){	TALLOC_CTX *local_ctx;        long long queryInt;	int rollback = 0;	char *errmsg;        char *schema;        int ret;	/* create a local ctx */	local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_rename local context");	if (local_ctx == NULL) {		return -1;	}	schema = lsqlite3_tprintf(local_ctx,                                                "CREATE TABLE ldb_info AS "                "  SELECT 'LDB' AS database_type,"                "         '1.0' AS version;"                                /*                 * The entry table holds the information about an entry.                  * This table is used to obtain the EID of the entry and to                  * support scope=one and scope=base.  The parent and child                 * table is included in the entry table since all the other                 * attributes are dependent on EID.                 */                "CREATE TABLE ldb_entry "                "("                "  eid     INTEGER PRIMARY KEY AUTOINCREMENT,"                "  dn      TEXT UNIQUE NOT NULL,"		"  norm_dn TEXT UNIQUE NOT NULL"                ");"                                "CREATE TABLE ldb_object_classes"                "("                "  class_name            TEXT PRIMARY KEY,"                "  parent_class_name     TEXT,"                "  tree_key              TEXT UNIQUE,"                "  max_child_num         INTEGER DEFAULT 0"                ");"                                /*                 * We keep a full listing of attribute/value pairs here                 */                "CREATE TABLE ldb_attribute_values"                "("                "  eid             INTEGER REFERENCES ldb_entry,"                "  attr_name       TEXT,"                "  norm_attr_name  TEXT,"                "  attr_value      TEXT,"                "  norm_attr_value TEXT "                ");"                                               /*                 * Indexes                 */                "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, norm_attr_value);"                                                /*                 * Triggers                 */                 "CREATE TRIGGER ldb_object_classes_insert_tr"                "  AFTER INSERT"                "  ON ldb_object_classes"                "  FOR EACH ROW"                "    BEGIN"                "      UPDATE ldb_object_classes"                "        SET tree_key = COALESCE(tree_key, "                "              ("                "                SELECT tree_key || "                "                       (SELECT base160(max_child_num + 1)"                "                                FROM ldb_object_classes"                "                                WHERE class_name = "                "                                      new.parent_class_name)"                "                  FROM ldb_object_classes "                "                  WHERE class_name = new.parent_class_name "                "              ));"                "      UPDATE ldb_object_classes "                "        SET max_child_num = max_child_num + 1"                "        WHERE class_name = new.parent_class_name;"                "    END;"                /*                 * Table initialization                 */                "INSERT INTO ldb_object_classes "                "    (class_name, tree_key) "                "  VALUES "                "    ('TOP', '0001');");                /* Skip protocol indicator of url  */        if (strncmp(url, "sqlite3://", 10) != 0) {                return SQLITE_MISUSE;        }                /* Update pointer to just after the protocol indicator */        url += 10;                /* Try to open the (possibly empty/non-existent) database */        if ((ret = sqlite3_open(url, &lsqlite3->sqlite)) != SQLITE_OK) {                return ret;        }                /* In case this is a new database, enable auto_vacuum */	ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA auto_vacuum = 1;", NULL, NULL, &errmsg);	if (ret != SQLITE_OK) {		if (errmsg) {			printf("lsqlite3 initializaion error: %s\n", errmsg);			free(errmsg);		}		goto failed;	}        	if (flags & LDB_FLG_NOSYNC) {		/* DANGEROUS */		ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA synchronous = OFF;", NULL, NULL, &errmsg);		if (ret != SQLITE_OK) {			if (errmsg) {				printf("lsqlite3 initializaion error: %s\n", errmsg);				free(errmsg);			}			goto failed;		}	}        	/* */                /* Establish a busy timeout of 30 seconds */        if ((ret = sqlite3_busy_timeout(lsqlite3->sqlite,                                        30000)) != SQLITE_OK) {                return ret;        }        /* Create a function, callable from sql, to increment a tree_key */        if ((ret =             sqlite3_create_function(lsqlite3->sqlite,/* handle */                                     "base160_next",  /* function name */                                     1,               /* number of args */                                     SQLITE_ANY,      /* preferred text type */                                     NULL,            /* user data */                                     base160next_sql, /* called func */                                     NULL,            /* step func */                                     NULL             /* final func */                     )) != SQLITE_OK) {                return ret;        }        /* Create a function, callable from sql, to convert int to base160 */        if ((ret =             sqlite3_create_function(lsqlite3->sqlite,/* handle */                                     "base160",       /* function name */                                     1,               /* number of args */                                     SQLITE_ANY,      /* preferred text type */                                     NULL,            /* user data */                                     base160_sql,     /* called func */                                     NULL,            /* step func */                                     NULL             /* final func */                     )) != SQLITE_OK) {                return ret;        }        /* Create a function, callable from sql, to perform various comparisons */        if ((ret =             sqlite3_create_function(lsqlite3->sqlite, /* handle */                                     "ldap_compare",   /* function name */                                     4,                /* number of args */                                     SQLITE_ANY,       /* preferred text type */                                     ldb  ,            /* user data */                                     lsqlite3_compare, /* called func */                                     NULL,             /* step func */                                     NULL              /* final func */                     )) != SQLITE_OK) {                return ret;        }        /* Begin a transaction */	ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN EXCLUSIVE;", NULL, NULL, &errmsg);	if (ret != SQLITE_OK) {		if (errmsg) {			printf("lsqlite3: initialization error: %s\n", errmsg);			free(errmsg);		}		goto failed;	}	rollback = 1;         /* Determine if this is a new database.  No tables means it is. */        if (query_int(lsqlite3,                      &queryInt,                      "SELECT COUNT(*)\n"                      "  FROM sqlite_master\n"                      "  WHERE type = 'table';") != 0) {		goto failed;        }                if (queryInt == 0) {                /*                 * Create the database schema                 */		ret = sqlite3_exec(lsqlite3->sqlite, schema, NULL, NULL, &errmsg);		if (ret != SQLITE_OK) {			if (errmsg) {				printf("lsqlite3 initializaion error: %s\n", errmsg);				free(errmsg);			}			goto failed;		}        } else {                /*                 * Ensure that the database we opened is one of ours                 */                if (query_int(lsqlite3,                              &queryInt,                              "SELECT "                              "  (SELECT COUNT(*) = 2"                              "     FROM sqlite_master "                              "     WHERE type = 'table' "                              "       AND name IN "                              "         ("                              "           'ldb_entry', "                              "           'ldb_object_classes' "                              "         ) "                              "  ) "                              "  AND "                              "  (SELECT 1 "                              "     FROM ldb_info "                              "     WHERE database_type = 'LDB' "                              "       AND version = '1.0'"                              "  );") != 0 ||                    queryInt != 1) {                                                /* It's not one that we created.  See ya! */			goto failed;                }        }                /* Commit the transaction */	ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg);	if (ret != SQLITE_OK) {		if (errmsg) {			printf("lsqlite3: iniialization error: %s\n", errmsg);			free(errmsg);		}		goto failed;	}         return SQLITE_OK;failed:	if (rollback) lsqlite3_safe_rollback(lsqlite3->sqlite); 	sqlite3_close(lsqlite3->sqlite);	return -1;}/* * connect to the database */static int lsqlite3_connect(struct ldb_context *ldb,			    const char *url, 			    unsigned int flags, 			    const char *options[],			    struct ldb_module **module){	int                         i;        int                         ret;	struct lsqlite3_private *   lsqlite3 = NULL;        	lsqlite3 = talloc(ldb, struct lsqlite3_private);	if (!lsqlite3) {		goto failed;	}        	lsqlite3->sqlite = NULL;	lsqlite3->options = NULL;	lsqlite3->trans_count = 0;        	ret = initialize(lsqlite3, ldb, url, flags);	if (ret != SQLITE_OK) {		goto failed;	}        	talloc_set_destructor(lsqlite3, destructor);        	*module = talloc(ldb, struct ldb_module);	if (!module) {		ldb_oom(ldb);		goto failed;	}	talloc_set_name_const(*module, "ldb_sqlite3 backend");	(*module)->ldb = ldb;	(*module)->prev = (*module)->next = NULL;	(*module)->private_data = lsqlite3;	(*module)->ops = &lsqlite3_ops;	if (options) {		/*                 * take a copy of the options array, so we don't have to rely                 * on the caller keeping it around (it might be dynamic)                 */		for (i=0;options[i];i++) ;                		lsqlite3->options = talloc_array(lsqlite3, char *, i+1);		if (!lsqlite3->options) {			goto failed;		}                		for (i=0;options[i];i++) {                        			lsqlite3->options[i+1] = NULL;			lsqlite3->options[i] =                                talloc_strdup(lsqlite3->options, options[i]);			if (!lsqlite3->options[i]) {				goto failed;			}		}	}        	return 0;        failed:        if (lsqlite3->sqlite != NULL) {                (void) sqlite3_close(lsqlite3->sqlite);        }	talloc_free(lsqlite3);	return -1;}const struct ldb_backend_ops ldb_sqlite3_backend_ops = {	.name = "sqlite3",	.connect_fn = lsqlite3_connect};

⌨️ 快捷键说明

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