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

📄 test1.c

📁 SQLite 2.8.6 源代码,用来在Linux/Unix/Windows上编译安装.它是一个小型的数据库,但是非常好用,速度也快,一般的数据库查询之类的操作据统计比MySQL,PostgreSQL
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 2001 September 15**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.***************************************************************************** Code for testing the printf() interface to SQLite.  This code** is not included in the SQLite library.  It is used for automated** testing of the SQLite library.**** $Id: test1.c,v 1.26 2003/07/09 00:28:15 drh Exp $*/#include "sqliteInt.h"#include "tcl.h"#include "os.h"#include <stdlib.h>#include <string.h>#if OS_WIN# define PTR_FMT "%x"#else# define PTR_FMT "%p"#endif/*** Decode a pointer to an sqlite object.*/static int getDbPointer(Tcl_Interp *interp, const char *zArg, sqlite **ppDb){  if( sscanf(zArg, PTR_FMT, (void**)ppDb)!=1 ){    Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0);    return TCL_ERROR;  }  return TCL_OK;}/*** Decode a pointer to an sqlite_vm object.*/static int getVmPointer(Tcl_Interp *interp, const char *zArg, sqlite_vm **ppVm){  if( sscanf(zArg, PTR_FMT, (void**)ppVm)!=1 ){    Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0);    return TCL_ERROR;  }  return TCL_OK;}/*** Generate a text representation of a pointer that can be understood** by the getDbPointer and getVmPointer routines above.**** The problem is, on some machines (Solaris) if you do a printf with** "%p" you cannot turn around and do a scanf with the same "%p" and** get your pointer back.  You have to prepend a "0x" before it will** work.  Or at least that is what is reported to me (drh).  But this** behavior varies from machine to machine.  The solution used her is** to test the string right after it is generated to see if it can be** understood by scanf, and if not, try prepending an "0x" to see if** that helps.  If nothing works, a fatal error is generated.*/static int makePointerStr(Tcl_Interp *interp, char *zPtr, void *p){  void *p2;  sprintf(zPtr, PTR_FMT, p);  if( sscanf(zPtr, PTR_FMT, &p2)!=1 || p2!=p ){    sprintf(zPtr, "0x" PTR_FMT, p);    if( sscanf(zPtr, PTR_FMT, &p2)!=1 || p2!=p ){      Tcl_AppendResult(interp, "unable to convert a pointer to a string "         "in the file " __FILE__ " in function makePointerStr().  Please "         "report this problem to the SQLite mailing list or as a new but "         "report.  Please provide detailed information about how you compiled "         "SQLite and what computer you are running on.", 0);      return TCL_ERROR;    }  }  return TCL_OK;}/*** Usage:   sqlite_open filename**** Returns:  The name of an open database.*/static int sqlite_test_open(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  sqlite *db;  char *zErr = 0;  char zBuf[100];  if( argc!=2 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],       " FILENAME\"", 0);    return TCL_ERROR;  }  db = sqlite_open(argv[1], 0666, &zErr);  if( db==0 ){    Tcl_AppendResult(interp, zErr, 0);    free(zErr);    return TCL_ERROR;  }  if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;  Tcl_AppendResult(interp, zBuf, 0);  return TCL_OK;}/*** The callback routine for sqlite_exec_printf().*/static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){  Tcl_DString *str = (Tcl_DString*)pArg;  int i;  if( Tcl_DStringLength(str)==0 ){    for(i=0; i<argc; i++){      Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL");    }  }  for(i=0; i<argc; i++){    Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL");  }  return 0;}/*** Usage:  sqlite_exec_printf  DB  FORMAT  STRING**** Invoke the sqlite_exec_printf() interface using the open database** DB.  The SQL is the string FORMAT.  The format string should contain** one %s or %q.  STRING is the value inserted into %s or %q.*/static int test_exec_printf(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  sqlite *db;  Tcl_DString str;  int rc;  char *zErr = 0;  char zBuf[30];  if( argc!=4 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],        " DB FORMAT STRING", 0);    return TCL_ERROR;  }  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;  Tcl_DStringInit(&str);  rc = sqlite_exec_printf(db, argv[2], exec_printf_cb, &str, &zErr, argv[3]);  sprintf(zBuf, "%d", rc);  Tcl_AppendElement(interp, zBuf);  Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);  Tcl_DStringFree(&str);  if( zErr ) free(zErr);  return TCL_OK;}/*** Usage:  sqlite_mprintf_z_test  SEPARATOR  ARG0  ARG1 ...**** Test the %z format of mprintf().  Use multiple mprintf() calls to ** concatenate arg0 through argn using separator as the separator.** Return the result.*/static int test_mprintf_z(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  char *zResult = 0;  int i;  for(i=2; i<argc; i++){    zResult = sqlite_mprintf("%z%s%s", zResult, argv[1], argv[i]);  }  Tcl_AppendResult(interp, zResult, 0);  sqlite_freemem(zResult);  return TCL_OK;}/*** Usage:  sqlite_get_table_printf  DB  FORMAT  STRING**** Invoke the sqlite_get_table_printf() interface using the open database** DB.  The SQL is the string FORMAT.  The format string should contain** one %s or %q.  STRING is the value inserted into %s or %q.*/static int test_get_table_printf(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  sqlite *db;  Tcl_DString str;  int rc;  char *zErr = 0;  int nRow, nCol;  char **aResult;  int i;  char zBuf[30];  if( argc!=4 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],        " DB FORMAT STRING", 0);    return TCL_ERROR;  }  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;  Tcl_DStringInit(&str);  rc = sqlite_get_table_printf(db, argv[2], &aResult, &nRow, &nCol,                &zErr, argv[3]);  sprintf(zBuf, "%d", rc);  Tcl_AppendElement(interp, zBuf);  if( rc==SQLITE_OK ){    sprintf(zBuf, "%d", nRow);    Tcl_AppendElement(interp, zBuf);    sprintf(zBuf, "%d", nCol);    Tcl_AppendElement(interp, zBuf);    for(i=0; i<(nRow+1)*nCol; i++){      Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");    }  }else{    Tcl_AppendElement(interp, zErr);  }  sqlite_free_table(aResult);  if( zErr ) free(zErr);  return TCL_OK;}/*** Usage:  sqlite_last_insert_rowid DB**** Returns the integer ROWID of the most recent insert.*/static int test_last_rowid(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  sqlite *db;  char zBuf[30];  if( argc!=2 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0);    return TCL_ERROR;  }  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;  sprintf(zBuf, "%d", sqlite_last_insert_rowid(db));  Tcl_AppendResult(interp, zBuf, 0);  return SQLITE_OK;}/*** Usage:  sqlite_close DB**** Closes the database opened by sqlite_open.*/static int sqlite_test_close(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  sqlite *db;  if( argc!=2 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],       " FILENAME\"", 0);    return TCL_ERROR;  }  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;  sqlite_close(db);  return TCL_OK;}/*** Implementation of the x_coalesce() function.** Return the first argument non-NULL argument.*/static void ifnullFunc(sqlite_func *context, int argc, const char **argv){  int i;  for(i=0; i<argc; i++){    if( argv[i] ){      sqlite_set_result_string(context, argv[i], -1);      break;    }  }}/*** Implementation of the x_sqlite_exec() function.  This function takes** a single argument and attempts to execute that argument as SQL code.** This is illegal and should set the SQLITE_MISUSE flag on the database.** ** This routine simulates the effect of having two threads attempt to** use the same database at the same time.*/static void sqliteExecFunc(sqlite_func *context, int argc, const char **argv){  sqlite_exec((sqlite*)sqlite_user_data(context), argv[0], 0, 0, 0);}/*** Usage:  sqlite_test_create_function DB**** Call the sqlite_create_function API on the given database in order** to create a function named "x_coalesce".  This function does the same thing** as the "coalesce" function.  This function also registers an SQL function** named "x_sqlite_exec" that invokes sqlite_exec().  Invoking sqlite_exec()** in this way is illegal recursion and should raise an SQLITE_MISUSE error.** The effect is similar to trying to use the same database connection from** two threads at the same time.**** The original motivation for this routine was to be able to call the** sqlite_create_function function while a query is in progress in order** to test the SQLITE_MISUSE detection logic.*/static int test_create_function(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  sqlite *db;  extern void Md5_Register(sqlite*);  if( argc!=2 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],       " FILENAME\"", 0);    return TCL_ERROR;  }  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;  sqlite_create_function(db, "x_coalesce", -1, ifnullFunc, 0);  sqlite_create_function(db, "x_sqlite_exec", 1, sqliteExecFunc, db);  return TCL_OK;}/*** Routines to implement the x_count() aggregate function.*/typedef struct CountCtx CountCtx;struct CountCtx {  int n;};static void countStep(sqlite_func *context, int argc, const char **argv){  CountCtx *p;  p = sqlite_aggregate_context(context, sizeof(*p));  if( (argc==0 || argv[0]) && p ){    p->n++;  }}   static void countFinalize(sqlite_func *context){  CountCtx *p;  p = sqlite_aggregate_context(context, sizeof(*p));  sqlite_set_result_int(context, p ? p->n : 0);}/*** Usage:  sqlite_test_create_aggregate DB**** Call the sqlite_create_function API on the given database in order** to create a function named "x_count".  This function does the same thing** as the "md5sum" function.**** The original motivation for this routine was to be able to call the** sqlite_create_aggregate function while a query is in progress in order** to test the SQLITE_MISUSE detection logic.*/static int test_create_aggregate(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  sqlite *db;  if( argc!=2 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],       " FILENAME\"", 0);    return TCL_ERROR;  }  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;  sqlite_create_aggregate(db, "x_count", 0, countStep, countFinalize, 0);  sqlite_create_aggregate(db, "x_count", 1, countStep, countFinalize, 0);  return TCL_OK;}/*** Usage:  sqlite_mprintf_int FORMAT INTEGER INTEGER INTEGER**** Call mprintf with three integer arguments*/static int sqlite_mprintf_int(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  int a[3], i;  char *z;  if( argc!=5 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],       " FORMAT INT INT INT\"", 0);    return TCL_ERROR;  }  for(i=2; i<5; i++){    if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;  }  z = sqlite_mprintf(argv[1], a[0], a[1], a[2]);  Tcl_AppendResult(interp, z, 0);  sqlite_freemem(z);  return TCL_OK;}/*** Usage:  sqlite_mprintf_str FORMAT INTEGER INTEGER STRING

⌨️ 快捷键说明

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