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

📄 main.cpp

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************  main.c  SQLite driver  iHacked by N.Gerrard from code originally provided by  (c) 2000-2003 Beno� Minisini <gambas@users.sourceforge.net>  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 1, or (at your option)  any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __MAIN_C#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <libgen.h> /* For basename function */#include <pwd.h>    /* For passwd file functions */#include <grp.h>    /* For group file functions */#include <sys/types.h>#include <sys/stat.h>#include <dirent.h>#include <unistd.h>#include "sqlitedataset.h"#include "main.h"extern "C" {GB_INTERFACE GB;DB_INTERFACE DB;} //end extern "C"static char _buffer[32];static int _print_query = FALSE;/*****************************************************************************  The driver interface*****************************************************************************/static DB_DRIVER _driver ={  "sqlite",  open_database,  close_database,  format_value,  exec_query,  begin_transaction,  commit_transaction,  rollback_transaction,  get_quote,  {    query_init,    query_fill,    query_release,    {      field_type,      field_name,      field_index,      field_length,    },  },  {    field_exist,    field_list,    field_info,  },  {    table_init,    table_index,    table_release,    table_exist,    table_list,    table_primary_key,    table_is_system,    table_type,    table_delete,    table_create,  },  {    index_exist,    index_list,    index_info,    index_delete,    index_create,  },  {    database_exist,    database_list,    database_is_system,    database_delete,    database_create,  },  {    user_exist,    user_list,    user_info,    user_delete,    user_create,    user_set_password  }};/* Internal function to convert a database type into a Gambas type */static GB_TYPE conv_type(int type){  switch(type)  {    case ft_Boolean:      return GB_T_BOOLEAN;    case ft_Short:    case ft_UShort:    case ft_Long:    case ft_ULong:      return GB_T_INTEGER;    case ft_Float:    case ft_Double:    case ft_LongDouble:      return GB_T_FLOAT;    case ft_Date:      return GB_T_DATE;    case ft_String:    case ft_WideString:    case ft_Char:    case ft_WChar:      return GB_T_STRING;    default:      return GB_T_STRING;  }}/* Internal function to convert a database value into a Gambas variant value */static void conv_data(char *data, GB_VARIANT_VALUE *val, fType type){  GB_VALUE conv;  GB_DATE_SERIAL date;  double sec;  switch (type)  {   case ft_Boolean:      val->_boolean.type = GB_T_BOOLEAN;      /*GB.NumberFromString(GB_NB_READ_INTEGER, data, strlen(data), &conv);*/      if (data[0] == 't' || data[0] == 'T'){	  val->_boolean.value = 1;      }      else {          val->_boolean.value = atoi(data);// != 0;      }      break;    case ft_Short:    case ft_UShort:    case ft_Long:    case ft_ULong:      GB.NumberFromString(GB_NB_READ_INTEGER, data, strlen(data), &conv);      val->_integer.type = GB_T_INTEGER;      val->_integer.value = ((GB_INTEGER *)&conv)->value;      break;    case ft_Float:    case ft_Double:    case ft_LongDouble:      GB.NumberFromString(GB_NB_READ_FLOAT, data, strlen(data), &conv);      val->_float.type = GB_T_FLOAT;      val->_float.value = ((GB_FLOAT *)&conv)->value;      break;    case ft_Date:      memset(&date, 0, sizeof(date));          switch(strlen(data))          {            case 14:              sscanf(data, "%4hu%2hu%2hu%2hu%2hu%lf", &date.year, &date.month, &date.day, &date.hour, &date.min, &sec);              date.sec = (short)sec;              date.msec = (short)((sec - date.sec) * 1000 + 0.5);              break;            case 12:              sscanf(data, "%2hu%2hu%2hu%2hu%2hu%lf", &date.year, &date.month, &date.day, &date.hour, &date.min, &sec);              date.sec = (short)sec;              date.msec = (short)((sec - date.sec) * 1000 + 0.5);              break;            case 10:	      if (sscanf(data, "%4hu-%2hu-%2hu", &date.year, &date.month,				  &date.day) != 3){	      	if (sscanf(data, "%4hu/%2hu/%2hu", &date.year, &date.month,				  &date.day) != 3){                   if (sscanf(data, "%4hu:%2hu:%lf", &date.hour, &date.min,			       &sec) == 3){                       date.sec = (short)sec;                       date.msec = (short)((sec - date.sec) * 1000 + 0.5);		   }		   else {	              sscanf(data, "%2hu%2hu%2hu%2hu%2hu", &date.year,	              &date.month, &date.day, &date.hour, &date.min );		   }	      	}	      }              break;            case 8:              if (sscanf(data, "%4hu%2hu%2hu", &date.year, &date.month,				      &date.day) != 3){                  sscanf(data, "%2hu/%2hu/%2hu", &date.year, &date.month,				 &date.day);	      }              break;            case 6:              sscanf(data, "%2hu%2hu%2hu", &date.year, &date.month, &date.day);              break;            case 4:              sscanf(data, "%2hu%2hu", &date.year, &date.month);              break;            case 2:              sscanf(data, "%2hu", &date.year);              break;	    default:              sscanf(data, "%4hu-%2hu-%2hu %2hu:%2hu:%lf", &date.year, &date.month, &date.day, &date.hour, &date.min, &sec);               date.sec = (short)sec;               date.msec = (short)((sec - date.sec) * 1000 + 0.5);          }          if (date.year < 100)              date.year=+1900;      GB.MakeDate(&date, (GB_DATE *)&conv);      val->_date.type = GB_T_DATE;      val->_date.date = ((GB_DATE *)&conv)->value.date;      val->_date.time = ((GB_DATE *)&conv)->value.time;      break;    case ft_String:    case ft_WideString:    case ft_Char:    case ft_WChar:    default:      val->_string.type = GB_T_CSTRING;      val->_string.value = data;      /*GB.NewString(&val->_string.value, data, strlen(data));*/      break;  }}/* Internal function to substitute the table name into a query */static char *query_param[3];static void query_get_param(int index, char **str, long *len){  if (index > 3)    return;  index--;  *str = query_param[index];  *len = strlen(*str);}/* Internal function to run a query */static int do_query(SqliteDatabase *conn, const char *error, Dataset **pres,                    const char *qtemp, int nsubst, ...){  va_list args;  int i;  const char *query;  Dataset *res = conn->CreateDataset();  int ret;  if (nsubst)  {    va_start(args, nsubst);    if (nsubst > 3)      nsubst = 3;    for (i = 0; i < nsubst; i++)      query_param[i] = va_arg(args, char *);    query = GB.SubstString(qtemp, 0, query_get_param);  }  else    query = qtemp;  if (_print_query)  {    _print_query = FALSE;  }  if (DB.IsDebug())    fprintf(stderr, "sqlite: %p: %s\n", conn, query);  if (strncasecmp("select",query,6) == 0){  	if(res->query(query)){          ret = FALSE;          if (pres){             *pres = res;          }        }        else {      	  ret = TRUE;          GB.Error(error, conn->getErrorMsg());          }  }  else {  	if(res->exec(query)){          ret = FALSE;          if (pres){             *pres = res;          }        }        else {      	  ret = TRUE;          GB.Error(error, conn->getErrorMsg());        }  }  return ret;}/* Internal function to check whether a file is a sqlite database file */bool IsDatabaseFile ( char *filename ){  /*                   SQLite databases start with the string:   *                  ** This file contains an SQLite 2.1 database **   *                                  */  FILE* fp;  bool res;  char magic_text[48];  fp = fopen(filename, "r");  if (!fp)    return false;  res = fread(magic_text, 1, 47, fp) == 47;  fclose(fp);  if (!res)    return false;  magic_text[47] = '\0';  if (strcmp(magic_text, "** This file contains an SQLite 2.1 database **"))    return false;  return true;}/* Internal function to locate database and return full qualified *//* path. */char *FindDatabase ( char *name, char *hostName){  char *dbhome = NULL;  char *fullpath = NULL;  /* Does Name includes fullpath */  if (strcmp(basename(name), name))  {    if (IsDatabaseFile(name))      GB.NewString(&fullpath, name, 0);    return fullpath;  }  /* Hostname contains home area */  GB.NewString(&fullpath, hostName, 0);      GB.AddString(&fullpath, "/", 0);  GB.AddString(&fullpath, name, 0);  if (IsDatabaseFile(fullpath)){     return fullpath;  }  GB.FreeString(&fullpath);  /* Check the GAMBAS_SQLITE_DBHOME setting */  dbhome = getenv("GAMBAS_SQLITE_DBHOME");  if (dbhome != NULL ){      GB.NewString(&fullpath, dbhome, 0);      GB.AddString(&fullpath, "/", 0);      GB.AddString(&fullpath, name, 0);      if (IsDatabaseFile(fullpath)){         return fullpath;      }  }  #if 0  /* Now check for database in current working directory */  if (getcwd(cwd, MAX_PATH) == NULL){      GB.Error("Unable to get databases: &1", "Can't find current directory");      return NULL;  }  #endif  GB.NewString(&fullpath, GB.GetTempDir(), 0);  GB.AddString(&fullpath, "/sqlite/", 0);  GB.AddString(&fullpath, name, 0);  if (IsDatabaseFile(fullpath)){     return fullpath;  }  GB.FreeString(&fullpath);  return NULL;}/* Internal function to return database home directory *//* - GAMBAS_SQLITE_HOMEDB if set or temporary directory /tmp/gambas.%pid%/ */char *GetDatabaseHome(){  char *env = NULL;  char *dbhome = NULL;  GB.Alloc((void **)&dbhome, MAX_PATH);  /* Check for Environment variable */  env = getenv("GAMBAS_SQLITE_DBHOME");  /* if not set then set to current working directory */  if (env == NULL){      /*     if (getcwd(dbhome, MAX_PATH) == NULL){         GB.Error("Unable to get databases: &1", "Can't find current directory");         GB.Free((void **)&dbhome);         return NULL;     }     */     sprintf(dbhome, "%s/sqlite", GB.GetTempDir());  }  else {     strcpy(dbhome, env);  }  return dbhome;}// BM: not used anymore#if 0/* Return Fullpath for database */char *FullPath( char *name ){  char *db_fullpath = NULL;  char *dbhome = NULL;  dbhome = GetDatabaseHome();  if (!dbhome)     return NULL;  GB.Alloc ((void **)&db_fullpath, strlen(name)+strlen(dbhome)+2); /* leave room							     for \0 and / */  /* start with an empty string */  db_fullpath[0] = '\0';  strcpy(db_fullpath, dbhome);  if (db_fullpath[strlen(db_fullpath)-1] != '/') {      strcat(db_fullpath, "/");  }  strcat(db_fullpath, name);  GB.Free((void **)&dbhome);  return db_fullpath;}#endif/* Internal function to walk a dirctory and list files *//* Used by database_list                               */int WalkDirectory( char *dir, char ***databases ){  DIR *dp;  struct dirent *entry;  struct stat statbuf;  char cwd[MAX_PATH];  if ((dp = opendir(dir)) == NULL) {      return -1;  }  getcwd(cwd, MAX_PATH);  chdir(dir);  while ((entry = readdir(dp)) != NULL) {	 stat(entry->d_name, &statbuf);	 if (S_ISREG(statbuf.st_mode)) {            if (IsDatabaseFile(entry->d_name)){                GB.NewString((char **)GB.Add(databases), entry->d_name, 0);	    }	 }  }  chdir(cwd);  // BM: you must call closedir()  closedir(dp);  return GB.Count(databases);}/* Internal function to check database version number */long db_version(){  //Check db version  long dbversion =0;  unsigned int verMain, verMajor, verMinor;  sscanf(sqlite_version,"%2u.%2u.%2u", &verMain, &verMajor, &verMinor);  dbversion = ((verMain * 10000) + (verMajor * 100) + verMinor);  return dbversion;}/*****************************************************************************  get_quote()  Returns the character used for quoting object names.*****************************************************************************/static char *get_quote(void){  return QUOTE_STRING;}/*****************************************************************************  open_database()  Connect to a database.  <desc> points at a structure describing each connection parameter.  In Sqlite, there is no such thing as a host.  If this is set then check  to see whether this is actually a path to a home area. NG 01/04/04  This function must return a database handle, or NULL if the connection  has failed.*****************************************************************************/static DB_DATABASE open_database(DB_DESC *desc, char **charset){  SqliteDatabase *conn = new SqliteDatabase();  char *name = NULL;  char *db_fullpath = NULL;  bool memory;  /* connect by default to memory database */  if (desc->name)  {    GB.NewString(&name, desc->name, 0);    memory = false;  }  else  {    GB.NewString(&name, ":memory:", 0);    memory = true;  }  if (desc->host)     conn->setHostName(desc->host);  if (memory)  {    conn->setDatabase(name);

⌨️ 快捷键说明

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