📄 main.cpp
字号:
Creates an index. <handle> is the database handle. <table> is the table name. <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((SqliteDatabase *)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. * SQLite: Databases are just files, so we need to ceck to see whether * the file exists and is a sqlite file. ******************************************************************************/static int database_exist(DB_DATABASE handle, char *name){ SqliteDatabase *conn = (SqliteDatabase *)handle; char *fullpath = NULL; if (strcmp(name,":memory:") == 0) return TRUE; //Database is loaded in memory only if((fullpath = FindDatabase(name, (char *)conn->getHostName())) != NULL){ GB.FreeString(&fullpath); return TRUE; } GB.FreeString(&fullpath); return FALSE;}/***************************************************************************** * * 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. * * Sqlite databases are files. Using we will only list * files within a designated directory. Propose that all * areas are walked through. ******************************************************************************/static long database_list(DB_DATABASE handle, char ***databases){ char *dbhome; SqliteDatabase *conn = (SqliteDatabase *)handle; GB.NewArray(databases, sizeof(char *), 0); /* Hostname contains home area */ dbhome = (char *)conn->getHostName(); WalkDirectory( dbhome, databases ); /* Checks GAMBAS_SQLITE_DBHOME if set, or Current Working Directory */ /* Might have to come back and seperate */ dbhome = GetDatabaseHome(); if (dbhome){ //GB.Error("Unable to get databases: &1", "Can't find current directory"); WalkDirectory( dbhome, databases ); GB.Free((void **)&dbhome); } /*if (getcwd(cwd, MAX_PATH) != NULL){ if (strcmp(cwd, dbhome) != 0){ WalkDirectory( cwd, databases ); } }*/ return GB.Count(databases);}/***************************************************************************** * * 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: Sqlite doesn't have such a thing. ******************************************************************************/static int database_is_system(DB_DATABASE handle, char *name){ return FALSE;}/***************************************************************************** * * 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){ char *fullpath = NULL; SqliteDatabase *conn = (SqliteDatabase *)handle; if((fullpath = FindDatabase(name, (char *)conn->getHostName())) == NULL){ GB.FreeString(&fullpath); GB.Error("Cannot Find database: &1", name); return TRUE; } if( remove(fullpath) != 0){ GB.Error("Unable to delete database &1", fullpath); GB.FreeString(&fullpath); return TRUE; } GB.FreeString(&fullpath); return FALSE;}/***************************************************************************** * * 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. * * SQLite automatically creates a database on connect if the file * does not exist. ******************************************************************************/static int database_create(DB_DATABASE handle, char *name){ SqliteDatabase *conn = (SqliteDatabase *)handle; SqliteDatabase conn2; char *fullpath = NULL; //char *homepath = NULL; //DIR *dp; char *dir; const char *host; /* Does Name includes fullpath */ /* BM: do not use basename(), it can modify its argument */ if (name && name[0] == '/') { GB.NewString(&fullpath, name, 0); goto _CREATE_DATABASE; } /* Hostname contains home area */ //if ((dp = opendir(conn->getHostName()))) /* BM: Why use opendir(), and why forget to call closedir() ? */ host = conn->getHostName(); if (host && host[0]) { GB.NewString(&fullpath, host, 0); } else { dir = GetDatabaseHome(); mkdir(dir, S_IRWXU); GB.NewString(&fullpath, dir, 0); GB.Free((void **)&dir); } if (fullpath[strlen(fullpath) - 1] != '/') GB.AddString(&fullpath, "/", 0); GB.AddString(&fullpath, name, 0);_CREATE_DATABASE: conn2.setDatabase(fullpath); GB.FreeString(&fullpath); if ( conn2.connect() != DB_CONNECTION_OK){ GB.Error("Cannot create database: &1", conn2.getErrorMsg()); conn2.disconnect(); return TRUE; } //Create and remove a table to initialize database if (!do_query(&conn2, "Unable to initialise database", NULL, "CREATE TABLE GAMBAS (FIELD1 TEXT)", 0)) do_query(&conn2, NULL, NULL, "DROP TABLE GAMBAS",0); conn2.disconnect(); return FALSE;}/***************************************************************************** * * 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. * Sqlite does not have different users. Access is controlled by * access rightd on the file. * We can check that the user exists on the machine and has access to * database file! * [Currently only checks against /etc/passwd. * Does not check against /etc/shadow or pam. * ******************************************************************************/static int user_exist(DB_DATABASE handle, char *name){ struct stat dbbuf; struct passwd *fileowner, *user; // /etc/passwd structure struct group *Group; // /etc/group structure char **Member; char *Databasefile; bool in_memory; SqliteDatabase *conn = (SqliteDatabase *)handle; if (( Databasefile = (char *)conn->getDatabase()) == NULL){ GB.Error("User_exist:&1", "Unable to get databasename"); return FALSE; } in_memory = strcmp(Databasefile, ":memory:") == 0; /* Is username in passwd file */ if ((user = getpwnam(name)) == NULL){ return FALSE; } if (in_memory) return (user->pw_uid == getuid()); if (stat(Databasefile, &dbbuf) != 0) { GB.Error("User_exist: Unable to get status of &1", Databasefile); return FALSE; } /* Now what are the database file permissions */ /* The order of tests is important */ if (( fileowner = getpwuid(dbbuf.st_uid)) != NULL){ if ( fileowner->pw_uid == user->pw_uid ){ /* User is owner */ if (( dbbuf.st_mode & S_IRUSR ) || (dbbuf.st_mode & S_IWUSR)){ return TRUE; } else { return FALSE; } } if ( fileowner->pw_gid == user->pw_gid ){ if (( dbbuf.st_mode & S_IRGRP ) || (dbbuf.st_mode & S_IWGRP)){ /* User has access to the file via primary group access.*/ return TRUE; } else { return FALSE; } } } /* Check whether user is in the same group */ Group = getgrgid(dbbuf.st_gid); Member = Group->gr_mem; while (Member && *Member){ if (strcmp(*Member, name) == 0){ //User is a member of the group if (( dbbuf.st_mode & S_IRGRP ) || (dbbuf.st_mode & S_IWGRP)){ return TRUE; } else { return FALSE; } } Member++; } if (( dbbuf.st_mode & S_IROTH ) || (dbbuf.st_mode & S_IWOTH)){ /* Any user can access this file */ return TRUE; } return FALSE;}/***************************************************************************** * * 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. * Sqlite does not have users. * ******************************************************************************/static long user_list(DB_DATABASE handle, char ***users){ //Should we use GB.HashTable.New etc. to ensure //duplicates are not reported back, then transfer //the valid elements to the Array. //Need to check order of rights. e.g. User overides //group and other, group overides other. //That is if the user is a member of a group that //is given no rights, but other has all rights, //they should not be able to access char *Databasefile; struct stat buf; struct passwd *user; // /etc/passwd structure struct group *Group; // /etc/group structure char **Member; int Count = 0; bool in_memory; SqliteDatabase *conn = (SqliteDatabase *)handle; if (( Databasefile = (char *)conn->getDatabase()) == NULL){ GB.Error("Unable to get databasename"); return -1; } in_memory = strcmp(Databasefile, ":memory:") == 0; if (in_memory) { buf.st_mode = S_IWUSR | S_IRUSR; buf.st_uid = getuid(); } else if (stat(Databasefile, &buf) != 0) { GB.Error("Unable to get status of &1", Databasefile); return -1; } if (users) GB.NewArray(users, sizeof(char *), 0); if (!in_memory) { /* If file has other access then any user could use it */ if (( buf.st_mode & S_IROTH ) || (buf.st_mode & S_IWOTH)){ /* Any user can access this file */ while (( user = getpwent()) != NULL ){ if (users){ GB.NewString((char **)GB.Add(users), user->pw_name, 0); } else { Count++; } } if (users){ return GB.Count(users); } else { return Count; } } /* If group access then add all users in the group */ if (( buf.st_mode & S_IRGRP ) || (buf.st_mode & S_IWGRP)){ Group = getgrgid(buf.st_gid); Member = Group->gr_mem; while (Member && *Member){ if (users){ GB.NewString((char **)GB.Add(users), *Member, 0); } else { Count++; } Member++; } } } /* Don't forget the owner if that has not already been added */ if (( buf.st_mode & S_IRUSR ) || (buf.st_mode & S_IWUSR)){ if (( user = getpwuid(buf.st_uid)) != NULL){ if (users){ GB.NewString((char **)GB.Add(users), user->pw_name, 0); } else { Count++; } } } if (users) return GB.Count(users); else 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. * * Sqlite privileges are just file privileges. We will return Admin * rights where privilege allows Write. There is no password. ******************************************************************************/static int user_info(DB_DATABASE handle, char *name, DB_USER *info ){ char *Databasefile; //struct stat buf; struct passwd *user; // /etc/passwd structure bool in_memory; //struct group *Group; // /etc/group structure //char **Member; //int Count; SqliteDatabase *conn = (SqliteDatabase *)handle; /* Is username in passwd file */ if ((user = getpwnam(name)) == NULL){ GB.Error("User_info: Invalid user &1", name); return TRUE; } if (( Databasefile = (char *)conn->getDatabase()) == NULL){ GB.Error("User_info: &1", "Unable to get databasename"); return TRUE; } in_memory = strcmp(Databasefile, ":memory:") == 0; if (in_memory) info->admin = true; else info->admin = access(Databasefile, W_OK); /* If file has other access then any user could use it */ //Need to look at order of checks info->name = NULL;// if (row[3]) //password does not exist for sqlite// GB.NewString(&info->password, row[3], 0); //password is encrypted in mysql 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. Sqlite users are operated by the O/S*****************************************************************************/static int user_delete(DB_DATABASE handle, char *name){ GB.Error("SQLite users do not exist."); return TRUE;}/***************************************************************************** * * 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. * * * Sqlite: No user create ******************************************************************************/static int user_create(DB_DATABASE handle, char *name, DB_USER *info){ GB.Error("SQLite users do not exist."); return TRUE;}/***************************************************************************** * * 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. * * Sqlite : No user passwords. ******************************************************************************/static int user_set_password(DB_DATABASE handle, char *name, char *password){ GB.Error("SQLite users do not exist."); return TRUE;}/***************************************************************************** The component entry and exit functions.*****************************************************************************/extern "C" {int GB_INIT(void){ GB.GetInterface("gb.db", DB_INTERFACE_VERSION, &DB); DB.Register(&_driver); return FALSE;}void GB_EXIT(){}} //extern "C"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -