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

📄 main.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************  main.c  MySQL 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 <mysql.h>#include "main.h"typedef  struct {    char *pattern;    int type;    }  CONV_STRING_TYPE;GB_INTERFACE GB;DB_INTERFACE DB;static char _buffer[125];static DB_DRIVER _driver;/*static int _print_query = FALSE;*//* Internal function to convert a database type into a Gambas type */static GB_TYPE conv_type(int type, int len){  switch(type)  {    case FIELD_TYPE_TINY:      return (len == 1 ? GB_T_BOOLEAN : GB_T_INTEGER);    case FIELD_TYPE_INT24:    case FIELD_TYPE_SHORT:    case FIELD_TYPE_LONG:    case FIELD_TYPE_LONGLONG:    case FIELD_TYPE_YEAR:      return GB_T_INTEGER;    case FIELD_TYPE_FLOAT:    case FIELD_TYPE_DOUBLE:    case FIELD_TYPE_DECIMAL:      return GB_T_FLOAT;    case FIELD_TYPE_DATE:    case FIELD_TYPE_DATETIME:    case FIELD_TYPE_TIME:    case FIELD_TYPE_TIMESTAMP:      return GB_T_DATE;    case FIELD_TYPE_BLOB:    case FIELD_TYPE_TINY_BLOB:    case FIELD_TYPE_MEDIUM_BLOB:    case FIELD_TYPE_LONG_BLOB:      return GB_T_STRING;    case FIELD_TYPE_STRING:    case FIELD_TYPE_VAR_STRING:    case FIELD_TYPE_SET:    case FIELD_TYPE_ENUM:    default:      return GB_T_STRING;  }}/* Internal function to convert a string database type into an integer database type */static int conv_string_type(const char *type, long *len){  static CONV_STRING_TYPE types[] =  {    { "tinyint", FIELD_TYPE_TINY },    { "smallint", FIELD_TYPE_SHORT },    { "mediumint", FIELD_TYPE_INT24 },    { "int", FIELD_TYPE_LONG },    { "bigint", FIELD_TYPE_LONGLONG },    { "decimal", FIELD_TYPE_DECIMAL },    { "numeric", FIELD_TYPE_DECIMAL },    { "float", FIELD_TYPE_FLOAT },    { "double", FIELD_TYPE_DOUBLE },    { "real", FIELD_TYPE_DOUBLE },    { "timestamp", FIELD_TYPE_TIMESTAMP },    { "date", FIELD_TYPE_DATE },    { "time", FIELD_TYPE_TIME },    { "datetime", FIELD_TYPE_DATETIME },    { "year", FIELD_TYPE_YEAR },    { "char", FIELD_TYPE_STRING },    { "varchar", FIELD_TYPE_VAR_STRING },    { "blob", FIELD_TYPE_BLOB },    { "tinyblob", FIELD_TYPE_TINY_BLOB },    { "mediumblob", FIELD_TYPE_MEDIUM_BLOB },    { "longblob", FIELD_TYPE_LONG_BLOB },    { "text", FIELD_TYPE_BLOB },    { "tinytext", FIELD_TYPE_TINY_BLOB },    { "mediumtext", FIELD_TYPE_MEDIUM_BLOB },    { "longtext", FIELD_TYPE_LONG_BLOB },    { "set", FIELD_TYPE_SET },    { "enum", FIELD_TYPE_ENUM },    { "null", FIELD_TYPE_NULL },    { NULL, 0 },  };  CONV_STRING_TYPE *cst;  long l;  if (strncmp(type, "national ", 9) == 0)    type += 9;  for (cst = types; cst->pattern; cst++)  {    if (strncmp(type, cst->pattern, strlen(cst->pattern)) == 0)      break;  }  if (cst->type)  {    if (len)    {      type += strlen(cst->pattern);      if (sscanf(type, "(%ld)", &l) == 1)        *len = l;      else        *len = 0;    }  }  return cst->type;}/* Internal function to convert a database value into a Gambas variant value */static void conv_data(char *data, GB_VARIANT_VALUE *val, int type, int len){  GB_VALUE conv;  GB_DATE_SERIAL date;  double sec;  switch (type)  {    case FIELD_TYPE_TINY:      if (len == 1)      {         val->_boolean.type = GB_T_BOOLEAN;         /*GB.NumberFromString(GB_NB_READ_INTEGER, data, strlen(data), &conv);*/         val->_boolean.value = atoi(data) != 0;      }      else      {        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 FIELD_TYPE_INT24:    case FIELD_TYPE_SHORT:    case FIELD_TYPE_LONG:    /*case FIELD_TYPE_TINY:*/    case FIELD_TYPE_LONGLONG:    case FIELD_TYPE_YEAR:      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 FIELD_TYPE_FLOAT:    case FIELD_TYPE_DOUBLE:    case FIELD_TYPE_DECIMAL:      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 FIELD_TYPE_DATE:    case FIELD_TYPE_DATETIME:    case FIELD_TYPE_TIME:    case FIELD_TYPE_TIMESTAMP:      memset(&date, 0, sizeof(date));      switch(type)      {        case FIELD_TYPE_DATE:          sscanf(data, "%4hu-%2hu-%2hu", &date.year, &date.month, &date.day);          break;        case FIELD_TYPE_TIME:          sscanf(data, "%4hu:%2hu:%lf", &date.hour, &date.min, &sec);          date.sec = (short)sec;          date.msec = (short)((sec - date.sec) * 1000 + 0.5);          break;        case FIELD_TYPE_DATETIME:          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 FIELD_TYPE_TIMESTAMP:          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:              sscanf(data, "%2hu%2hu%2hu%2hu%2hu", &date.year, &date.month, &date.day, &date.hour, &date.min );              break;            case 8:              sscanf(data, "%4hu%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;          }          if (date.year < 100)              date.year=+1900;        break;      }      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 FIELD_TYPE_STRING:    case FIELD_TYPE_VAR_STRING:    case FIELD_TYPE_SET:    case FIELD_TYPE_ENUM:    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(MYSQL *conn, const char *error, MYSQL_RES **pres,                    const char *qtemp, int nsubst, ...){  va_list args;  int i;  const char *query;  MYSQL_RES *res;  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 (DB.IsDebug())    fprintf(stderr, "mysql: %p: %s\n", conn, query);  if(mysql_query(conn, query)){    ret = TRUE;    GB.Error(error, mysql_error(conn));  }  else {    res = mysql_store_result(conn);    ret = FALSE;    if (pres)      *pres = res;    else      mysql_free_result(res);  }  return ret;}/* Internal function to check database version number */long db_version(MYSQL *conn){  //Check db version  const char *vquery = "select left(version(),6)";  long dbversion =0;  MYSQL_RES *res;  MYSQL_ROW row;  if (!do_query(conn, NULL, &res, vquery, 0))  {     unsigned int verMain, verMajor, verMinor;     row = mysql_fetch_row(res);     sscanf(row[0],"%2u.%2u.%2u", &verMain, &verMajor, &verMinor);     dbversion = ((verMain * 10000) + (verMajor * 100) + verMinor);     mysql_free_result(res);  }  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.  This function must return a database handle, or NULL if the connection  has failed.*****************************************************************************/static DB_DATABASE open_database(DB_DESC *desc, char **charset){  MYSQL *conn;  char *name;  conn = mysql_init(NULL);  /* (BM) connect by default to the mysql database */  if (desc->name)    name = desc->name;  else    name = "mysql"; /* Note: Users may not have access to database mysql */  //mysql_options(conn, MYSQL_READ_DEFAULT_GROUP,"Gambas");  //fprintf(stderr, "mysql_real_connect: host = '%s'\n", desc->host);  if (!mysql_real_connect( conn, desc->host, desc->user, desc->password,		  name, desc->port == NULL ? 0 : atoi(desc->port), NULL, /*unix_socket: if not null the	string specifies the socket  or named pipe that should be used */		  0 /*client flag */)){    mysql_close(conn);    GB.Error("Cannot open database: &1", mysql_error(conn));    return NULL;  }  /* Character Set cannot be set at this point int time */  //printf("Character set GB[%s] mysql[%s]\n", GB.System.Charset(), mysql_character_set_name(conn));  GB.NewString(charset, mysql_character_set_name(conn), 0);  /* set dbversion */  desc->version = db_version(conn);  return (DB_DATABASE)conn;}/*****************************************************************************  close_database()  Terminates the database connection.  <handle> contains the database handle.*****************************************************************************/static void close_database(DB_DATABASE handle){  MYSQL *conn = (MYSQL *)handle;  if (conn)    mysql_close(conn);}/*****************************************************************************  format_value()  This function transforms a gambas value into a string value that can  be inserted into a SQL query.  <arg> points to the value.  <add> is a callback called to insert the string into the query.  This function must return TRUE if it translates the value, and FALSE if  it does not.  If the value is not translated, then a default translation is used.*****************************************************************************/static int format_value(GB_VALUE *arg, DB_FORMAT_CALLBACK add){  int l;  GB_DATE_SERIAL *date;  switch (arg->type)  {    case GB_T_BOOLEAN:/*Note this is likely to go to a tinyint  */      if (VALUE((GB_BOOLEAN *)arg))         add("'1'", 3);      else        add("'0'", 3);      return TRUE;    case GB_T_STRING:    case GB_T_CSTRING:      return FALSE;    case GB_T_DATE:      date = GB.SplitDate((GB_DATE *)arg);      l = sprintf(_buffer, "'%04d-%02d-%02d %02d:%02d:%02d",          date->year, date->month, date->day,          date->hour, date->min, date->sec);          add(_buffer, l);          if (date->msec)          {            l = sprintf(_buffer, ".%03d", date->msec);            add(_buffer, l);          }          add("'", 1);          return TRUE;    default:      return FALSE;  }}/*****************************************************************************  exec_query()  Send a query to the server and gets the result.  <handle> is the database handle, as returned by open_database()  <query> is the query string.  <result> will receive the result handle of the query.  <err> is an error message used when the query failed.  <result> can be NULL, when we don't care getting the result.*****************************************************************************/static int exec_query(DB_DATABASE handle, char *query, DB_RESULT *result, char *err){  return do_query((MYSQL *)handle, err, (MYSQL_RES **)result, query, 0);}/*****************************************************************************  query_init()  Initialize an info structure from a query result.  <result> is the handle of the query result.  <info> points to the info structure.  <count> will receive the number of records returned by the query.  This function must initialize the info->nfield field with the number of  field in the query result.*****************************************************************************/static void query_init(DB_RESULT result, DB_INFO *info, int *count){  MYSQL_RES *res = (MYSQL_RES *)result;  if(res)  {        *count = mysql_num_rows(res);        info->nfield = mysql_num_fields(res);  }  else {        *count = 0;	info->nfield = 0;  }}/*****************************************************************************  query_release()  Free the info structure filled by query_init() and the result handle.  <result> is the handle of the query result.  <info> points to the info structure.*****************************************************************************/static void query_release(DB_RESULT result, DB_INFO *info){  mysql_free_result((MYSQL_RES *)result);}

⌨️ 快捷键说明

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