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

📄 test1.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
/*** 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 all sorts of SQLite interfaces.  This code** is not included in the SQLite library.  It is used for automated** testing of the SQLite library.**** $Id: test1.c,v 1.258 2007/06/26 00:37:28 drh Exp $*/#include "sqliteInt.h"#include "tcl.h"#include "os.h"#include <stdlib.h>#include <string.h>/*** This is a copy of the first part of the SqliteDb structure in ** tclsqlite.c.  We need it here so that the get_sqlite_pointer routine** can extract the sqlite3* pointer from an existing Tcl SQLite** connection.*/struct SqliteDb {  sqlite3 *db;};/*** Convert text generated by the "%p" conversion format back into** a pointer.*/static int testHexToInt(int h){  if( h>='0' && h<='9' ){    return h - '0';  }else if( h>='a' && h<='f' ){    return h - 'a' + 10;  }else{    assert( h>='A' && h<='F' );    return h - 'A' + 10;  }}void *sqlite3TextToPtr(const char *z){  void *p;  u64 v;  u32 v2;  if( z[0]=='0' && z[1]=='x' ){    z += 2;  }  v = 0;  while( *z ){    v = (v<<4) + testHexToInt(*z);    z++;  }  if( sizeof(p)==sizeof(v) ){    memcpy(&p, &v, sizeof(p));  }else{    assert( sizeof(p)==sizeof(v2) );    v2 = (u32)v;    memcpy(&p, &v2, sizeof(p));  }  return p;}/*** A TCL command that returns the address of the sqlite* pointer** for an sqlite connection instance.  Bad things happen if the** input is not an sqlite connection.*/static int get_sqlite_pointer(  void * clientData,  Tcl_Interp *interp,  int objc,  Tcl_Obj *CONST objv[]){  struct SqliteDb *p;  Tcl_CmdInfo cmdInfo;  char zBuf[100];  if( objc!=2 ){    Tcl_WrongNumArgs(interp, 1, objv, "SQLITE-CONNECTION");    return TCL_ERROR;  }  if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){    Tcl_AppendResult(interp, "command not found: ",           Tcl_GetString(objv[1]), (char*)0);    return TCL_ERROR;  }  p = (struct SqliteDb*)cmdInfo.objClientData;  sprintf(zBuf, "%p", p->db);  if( strncmp(zBuf,"0x",2) ){    sprintf(zBuf, "0x%p", p->db);  }  Tcl_AppendResult(interp, zBuf, 0);  return TCL_OK;}/*** Decode a pointer to an sqlite3 object.*/static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){  struct SqliteDb *p;  Tcl_CmdInfo cmdInfo;  if( Tcl_GetCommandInfo(interp, zA, &cmdInfo) ){    p = (struct SqliteDb*)cmdInfo.objClientData;    *ppDb = p->db;  }else{    *ppDb = (sqlite3*)sqlite3TextToPtr(zA);  }  return TCL_OK;}const char *sqlite3TestErrorName(int rc){  const char *zName = 0;  switch( rc & 0xff ){    case SQLITE_OK:         zName = "SQLITE_OK";          break;    case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;    case SQLITE_PERM:       zName = "SQLITE_PERM";        break;    case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;    case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;    case SQLITE_LOCKED:     zName = "SQLITE_LOCKED";      break;    case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;    case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;    case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;    case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;    case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;    case SQLITE_FULL:       zName = "SQLITE_FULL";        break;    case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;    case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;    case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;    case SQLITE_SCHEMA:     zName = "SQLITE_SCHEMA";      break;    case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT";  break;    case SQLITE_MISMATCH:   zName = "SQLITE_MISMATCH";    break;    case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;    case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;    case SQLITE_AUTH:       zName = "SQLITE_AUTH";        break;    case SQLITE_FORMAT:     zName = "SQLITE_FORMAT";      break;    case SQLITE_RANGE:      zName = "SQLITE_RANGE";       break;    case SQLITE_ROW:        zName = "SQLITE_ROW";         break;    case SQLITE_DONE:       zName = "SQLITE_DONE";        break;    case SQLITE_NOTADB:     zName = "SQLITE_NOTADB";      break;    default:                zName = "SQLITE_Unknown";     break;  }  return zName;}#define t1ErrorName sqlite3TestErrorName/*** Convert an sqlite3_stmt* into an sqlite3*.  This depends on the** fact that the sqlite3* is the first field in the Vdbe structure.*/#define StmtToDb(X)   sqlite3_db_handle(X)/*** Check a return value to make sure it agrees with the results** from sqlite3_errcode.*/int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){  if( rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){    char zBuf[200];    int r2 = sqlite3_errcode(db);    sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)",       t1ErrorName(rc), rc, t1ErrorName(r2), r2);    Tcl_ResetResult(interp);    Tcl_AppendResult(interp, zBuf, 0);    return 1;  }  return 0;}/*** Decode a pointer to an sqlite3_stmt object.*/static int getStmtPointer(  Tcl_Interp *interp,   const char *zArg,    sqlite3_stmt **ppStmt){  *ppStmt = (sqlite3_stmt*)sqlite3TextToPtr(zArg);  return TCL_OK;}/*** Decode a pointer to an sqlite3_stmt object.*/static int getFilePointer(  Tcl_Interp *interp,   const char *zArg,    OsFile **ppFile){  *ppFile = (OsFile*)sqlite3TextToPtr(zArg);  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.*/int sqlite3TestMakePointerStr(Tcl_Interp *interp, char *zPtr, void *p){  sqlite3_snprintf(100, zPtr, "%p", p);  return TCL_OK;}/*** The callback routine for sqlite3_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;}/*** The I/O tracing callback.*/static FILE *iotrace_file = 0;static void io_trace_callback(const char *zFormat, ...){  va_list ap;  va_start(ap, zFormat);  vfprintf(iotrace_file, zFormat, ap);  va_end(ap);  fflush(iotrace_file);}/*** Usage:  io_trace FILENAME**** Turn I/O tracing on or off.  If FILENAME is not an empty string,** I/O tracing begins going into FILENAME. If FILENAME is an empty** string, I/O tracing is turned off.*/static int test_io_trace(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  if( argc!=2 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],          " FILENAME\"", 0);    return TCL_ERROR;  }  if( iotrace_file ){    if( iotrace_file!=stdout && iotrace_file!=stderr ){      fclose(iotrace_file);    }    iotrace_file = 0;    sqlite3_io_trace = 0;  }  if( argv[1][0] ){    if( strcmp(argv[1],"stdout")==0 ){      iotrace_file = stdout;    }else if( strcmp(argv[1],"stderr")==0 ){      iotrace_file = stderr;    }else{      iotrace_file = fopen(argv[1], "w");    }    sqlite3_io_trace = io_trace_callback;  }  return SQLITE_OK;}/*** Usage:  sqlite3_exec_printf  DB  FORMAT  STRING**** Invoke the sqlite3_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 */){  sqlite3 *db;  Tcl_DString str;  int rc;  char *zErr = 0;  char *zSql;  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);  zSql = sqlite3_mprintf(argv[2], argv[3]);  rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);  sqlite3_free(zSql);  sprintf(zBuf, "%d", rc);  Tcl_AppendElement(interp, zBuf);  Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);  Tcl_DStringFree(&str);  if( zErr ) sqlite3_free(zErr);  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;  return TCL_OK;}/*** Usage:  sqlite3_exec  DB  SQL**** Invoke the sqlite3_exec interface using the open database DB*/static int test_exec(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  sqlite3 *db;  Tcl_DString str;  int rc;  char *zErr = 0;  char *zSql;  int i, j;  char zBuf[30];  if( argc!=3 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],        " DB SQL", 0);    return TCL_ERROR;  }  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;  Tcl_DStringInit(&str);  zSql = sqlite3_mprintf("%s", argv[2]);  for(i=j=0; zSql[i];){    if( zSql[i]=='%' ){      zSql[j++] = (testHexToInt(zSql[i+1])<<4) + testHexToInt(zSql[i+2]);      i += 3;    }else{      zSql[j++] = zSql[i++];    }  }  zSql[j] = 0;  rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);  sqlite3_free(zSql);  sprintf(zBuf, "%d", rc);  Tcl_AppendElement(interp, zBuf);  Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);  Tcl_DStringFree(&str);  if( zErr ) sqlite3_free(zErr);  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;  return TCL_OK;}/*** Usage:  sqlite3_exec_nr  DB  SQL**** Invoke the sqlite3_exec interface using the open database DB.  Discard** all results*/static int test_exec_nr(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  sqlite3 *db;  int rc;  char *zErr = 0;  if( argc!=3 ){    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],        " DB SQL", 0);    return TCL_ERROR;  }  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;  rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;  return TCL_OK;}/*** Usage:  sqlite3_mprintf_z_test  SEPARATOR  ARG0  ARG1 ...**** Test the %z format of sqliteMPrintf().  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 = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]);  }  Tcl_AppendResult(interp, zResult, 0);  sqliteFree(zResult);  return TCL_OK;}/*** Usage:  sqlite3_mprintf_n_test  STRING**** Test the %n format of sqliteMPrintf().  Return the length of the** input string.*/static int test_mprintf_n(  void *NotUsed,  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */  int argc,              /* Number of arguments */  char **argv            /* Text of each argument */){  char *zStr;  int n = 0;  zStr = sqlite3MPrintf("%s%n", argv[1], &n);  sqliteFree(zStr);  Tcl_SetObjResult(interp, Tcl_NewIntObj(n));  return TCL_OK;}/*** Usage:  sqlite3_snprintf_int  SIZE FORMAT  INT**** Test the of sqlite3_snprintf() routine.  SIZE is the size of the** output buffer in bytes.  The maximum size is 100.  FORMAT is the** format string.  INT is a single integer argument.  The FORMAT** string must require no more than this one integer argument.  If** You pass in a format string that requires more than one argument,

⌨️ 快捷键说明

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