📄 main.c
字号:
<index> is the index name. <info> points to a structure describing the index. This function returns TRUE if the command has failed, and FALSE if everything was OK.*****************************************************************************/static int index_create(DB_DATABASE handle, char *table, char *index, DB_INDEX *info){ DB.Query.Init(); DB.Query.Add("CREATE "); if (info->unique) DB.Query.Add("UNIQUE "); DB.Query.Add("INDEX `"); DB.Query.Add(index); DB.Query.Add("` ON "); DB.Query.Add(table); DB.Query.Add(" ( "); DB.Query.Add(info->fields); DB.Query.Add(" )"); return do_query((MYSQL *)handle, "Cannot create index: &1", NULL, DB.Query.Get(), 0);}/***************************************************************************** * * database_exist() * * Returns if a database exists * * <handle> is any database handle. * <name> is the database name. * * This function returns TRUE if the database exists, and FALSE if not. * ******************************************************************************/static int database_exist(DB_DATABASE handle, char *name){ MYSQL *conn = (MYSQL *)handle; MYSQL_RES *res; int exist; res = mysql_list_dbs( conn, name); if (!res){ GB.Error("Unable to check database: &1", mysql_error(conn)); return FALSE; } exist = mysql_num_rows(res); mysql_free_result(res); return exist;}/***************************************************************************** * * database_list() * * Returns an array containing the name of each database * * <handle> is any database handle. * <databases> points to a variable that will receive the char* array. * * This function returns the number of databases, or -1 if the command has * failed. * * Be careful: <databases> can be NULL, so that just the count is returned. * ******************************************************************************/static long database_list(DB_DATABASE handle, char ***databases){ long i, rows; MYSQL *conn = (MYSQL *)handle; MYSQL_RES *res; MYSQL_ROW row; res = mysql_list_dbs( conn, 0); if (!res){ GB.Error("Unable to get databases: &1", mysql_error(conn)); return -1; } rows = mysql_num_rows(res); /*printf("Got %d databases\n", rows); */ GB.NewArray(databases, sizeof(char *), rows); for (i = 0; i < rows; i++){ row = mysql_fetch_row(res); GB.NewString(&(*databases)[i], row[0], 0); /*printf("%s\n", (*databases)[i]); */ } mysql_free_result(res); return rows;}/***************************************************************************** * * database_is_system() * * Returns if a database is a system database. * * <handle> is any database handle. * <name> is the database name. * * This function returns TRUE if the database is a system database, and * FALSE if not. * Note: In mysql the mysql database is the only system database. ******************************************************************************/static int database_is_system(DB_DATABASE handle, char *name){ return (strcmp("mysql", name) == 0);}/***************************************************************************** * * database_delete() * * Deletes a database. * * <handle> is the database handle. * <name> is the database name. * * This function returns TRUE if the command has failed, and FALSE if * everything was OK. * ******************************************************************************/static int database_delete(DB_DATABASE handle, char *name){ return do_query((MYSQL *)handle, "Unable to delete database: &1", NULL, "drop database `&1`", 1, name);}/***************************************************************************** * * database_create() * * Creates a database. * * <handle> is the database handle. * <name> is the database name. * * This function returns TRUE if the command has failed, and FALSE if * everything was OK. * ******************************************************************************/static int database_create(DB_DATABASE handle, char *name){ return do_query((MYSQL *)handle, "Unable to create database: &1", NULL, "create database `&1`", 1, name);}/***************************************************************************** * * user_exist() * * Returns if a user exists. * * <handle> is any database handle. * <name> is the user name. * * This function returns TRUE if the user exists, and FALSE if not. * ******************************************************************************/static int user_exist(DB_DATABASE handle, char *name){ const char *query = "select user from mysql.user " "where user = '&1' and host = '&2' "; MYSQL_RES *res; int exist; char *_name, *_host, *_token; if (!strrchr(name,'@')){ //To be done: maybe we should check hostname we are running //from and use this instead of localhost /* (BM) you forgot the last 0 character */ _name = malloc(strlen(name) + strlen("@localhost") + 1); sprintf(_name,"%s@localhost", name); } else { _name = malloc(strlen(name) + 1); strcpy(_name,name); } _host = strrchr(_name,'@') + 1; _token = _host - 1; _token[0] = (char) NULL; if (do_query((MYSQL *)handle, "Unable to check user: &1@&2", &res, query, 2, _name, _host)){ free(_name); //free(_host); return FALSE; } exist = mysql_num_rows(res) == 1; free(_name); //free(_host); mysql_free_result(res); return exist;}/***************************************************************************** * * user_list() * * Returns an array containing the name of each user. * * <handle> is the database handle. * <users> points to a variable that will receive the char* array. * * This function returns the number of users, or -1 if the command has * failed. * * Be careful: <users> can be NULL, so that just the count is returned. * ******************************************************************************/static long user_list(DB_DATABASE handle, char ***users){ const char *query = "select user, host from mysql.user"; MYSQL_RES *res; MYSQL_ROW row; MYSQL_FIELD *field; long i, count, length; char *_username; if (do_query((MYSQL *)handle, "Unable to get users: &1", &res, query, 0)) return -1; count = mysql_num_rows(res); if (users) { GB.NewArray(users, sizeof(char *), count); field = mysql_fetch_field(res); //user field length = field->max_length; field = mysql_fetch_field(res); //host field length += field->max_length; _username = malloc(length + 2); /* (BM) +2 because there is the last 0 character ! */ for ( i = 0; i < count; i++ ) { row = mysql_fetch_row(res); sprintf(_username,"%s@%s", row[0], row[1]); GB.NewString(&(*users)[i], _username, 0); } free(_username); } mysql_free_result(res); return count;}/***************************************************************************** * * user_info() * * Get user description * * <handle> is the database handle. * <name> is the user name. * <info> points to a structure filled by the function. * * This function returns TRUE if the command has failed, and FALSE if * everything was OK. * * Mysql notes: Privileges set to Y in the mysql.user table are global settings * and apply to all databases. eg. These are super user privileges. * mysql.tables_priv lists the access granted to a user on a * particular table * mysql.columns_priv grant column specific privileges. * mysql.db and mysql.host grant database specific privileges. * * User may also not be unique as mysql.user also contains * users from different hosts. e.g host and user columns will * make it unique! Using 'localhost' here to limit. * * The privileges are: grant_priv - allows user to grant * privileges to others - which * includes the ability to create * users; * create_priv/drop_priv - create database, * tables etc. ******************************************************************************/static int user_info(DB_DATABASE handle, char *name, DB_USER *info ){ const char *query = "select create_priv, drop_priv, grant_priv, password from mysql.user " "where user = '&1' and host = '&2'"; MYSQL_RES *res; MYSQL_ROW row; char *_name, *_host, *_token; if (!strrchr(name,'@')){ //To be done: check hostname we are running //from use instead of localhost /* (BM) You forgot the last 0 character */ _name = malloc(strlen(name) + strlen("@localhost") + 1); sprintf(_name,"%s@localhost", name); } else { _name = malloc(strlen(name) + 1); strcpy(_name,name); } _host = strrchr(_name,'@') + 1; _token = _host - 1; _token[0] = (char) NULL; if (do_query((MYSQL *)handle, "Unable to check user info: &1@&2", &res, query, 2, _name, _host)){ free(_name); return TRUE; } if (mysql_num_rows(res) != 1){ GB.Error("user_info: Non unique user found"); free(_name); mysql_free_result(res); return TRUE; } row = mysql_fetch_row(res); info->name = NULL; if ( strcmp(row[0], "Y") == 0 || strcmp(row[1], "Y") == 0) info->admin = 1; else info->admin = 0; if (row[3]) GB.NewString(&info->password, row[3], 0); //password is encrypted in mysql mysql_free_result(res); free(_name); return FALSE;}/***************************************************************************** user_delete() Deletes a user. <handle> is any database handle. <name> is the user name. This function returns TRUE if the command has failed, and FALSE if everything was OK.*****************************************************************************/static int user_delete(DB_DATABASE handle, char *name){ const char *_delete = "delete from mysql.user where user = '&1' and host = '&2'"; // "delete from mysql.user, mysql.db, mysql.columns_priv, mysql.tables_priv " // "where user = '&1' and host = '&2'"; char *_name, *_host, *_token; int _ret; if (!strrchr(name,'@')){ //To be done: maybe hostname we are running //from should be used rather than localhost _name = malloc(strlen(name) + strlen("@localhost")) + 1; sprintf(_name,"%s@localhost", name); } else { _name = malloc(strlen(name) + 1); strcpy(_name,name); } _host = strrchr(_name,'@') + 1; _token = _host - 1; _token[0] = (char) NULL; //Still need to look at the removal of privileges // _ret = do_query((MYSQL *)handle, "Unable to delete user: &1", NULL, // "revoke all on *.* from &1@&2", 2, _name, _host); _ret = do_query((MYSQL *)handle, "Unable to delete user: &1", NULL, _delete, 2, _name, _host); free(_name); return _ret;}/***************************************************************************** * * user_create() * * Creates a user. * * <handle> is the database handle. * <name> is the user name. * <info> points to a structure describing the user. * * This function returns TRUE if the command has failed, and FALSE if * everything was OK. * ******************************************************************************/static int user_create(DB_DATABASE handle, char *name, DB_USER *info){ char *_name; DB.Query.Init(); if (!strrchr(name,'@')){ _name = malloc(strlen(name) + strlen("@localhost") + 1); sprintf(_name,"%s@localhost", name); } else { _name = malloc(strlen(name) + 1); strcpy(_name,name); } if (info->admin) { DB.Query.Add("GRANT ALL PRIVILEGES ON *.* TO "); DB.Query.Add(_name); } else { DB.Query.Add("GRANT USAGE ON * TO "); DB.Query.Add(_name); } if (info->password) { DB.Query.Add(" IDENTIFIED BY '"); DB.Query.Add(info->password); DB.Query.Add("'"); } if (info->admin) DB.Query.Add(" WITH GRANT OPTION"); free(_name); return do_query((MYSQL *)handle, "Cannot create user: &1", NULL, DB.Query.Get(), 0);}/***************************************************************************** * * user_set_password() * * Change the user password. * * <handle> is the database handle. * <name> is the user name. * <password> is the new password * * This function returns TRUE if the command has failed, and FALSE if * everything was OK. * ******************************************************************************/static int user_set_password(DB_DATABASE handle, char *name, char *password){ char *_name; DB.Query.Init(); if (!strrchr(name,'@')){ _name = malloc(strlen(name) + strlen("@localhost") + 1); sprintf(_name,"%s@localhost", name); } else { _name = malloc(strlen(name) + 1); strcpy(_name,name); } DB.Query.Add("SET PASSWORD FOR "); DB.Query.Add(_name); DB.Query.Add(" = PASSWORD ('"); DB.Query.Add(password); DB.Query.Add("')"); free(_name); return do_query((MYSQL *)handle, "Cannot change user password: &1", NULL, DB.Query.Get(), 0);}/***************************************************************************** The driver interface*****************************************************************************/static DB_DRIVER _driver ={ "mysql", (void *)open_database, (void *)close_database, (void *)format_value, (void *)exec_query, (void *)begin_transaction, (void *)commit_transaction, (void *)rollback_transaction, (void *)get_quote, { (void *)query_init, (void *)query_fill, (void *)query_release, { (void *)field_type, (void *)field_name, (void *)field_index, (void *)field_length, }, }, { (void *)field_exist, (void *)field_list, (void *)field_info, }, { (void *)table_init, (void *)table_index, (void *)table_release, (void *)table_exist, (void *)table_list, (void *)table_primary_key, (void *)table_is_system, (void *)table_type, (void *)table_delete, (void *)table_create, }, { (void *)index_exist, (void *)index_list, (void *)index_info, (void *)index_delete, (void *)index_create, }, { (void *)database_exist, (void *)database_list, (void *)database_is_system, (void *)database_delete, (void *)database_create, }, { (void *)user_exist, (void *)user_list, (void *)user_info, (void *)user_delete, (void *)user_create, (void *)user_set_password }};/***************************************************************************** The component entry and exit functions.*****************************************************************************/int GB_INIT(void){ GB.GetInterface("gb.db", DB_INTERFACE_VERSION, &DB); DB.Register(&_driver); return FALSE;}void GB_EXIT(){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -