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

📄 tclsqlite.c

📁 sqlite-3.4.1,嵌入式数据库.是一个功能强大的开源数据库,给学习和研发以及小型公司的发展带来了全所未有的好处.
💻 C
📖 第 1 页 / 共 5 页
字号:
    zFile = Tcl_GetStringFromObj(objv[4], 0);    nSep = strlen(zSep);    nNull = strlen(zNull);    if( nSep==0 ){      Tcl_AppendResult(interp,"Error: non-null separator required for copy",0);      return TCL_ERROR;    }    if(sqlite3StrICmp(zConflict, "rollback") != 0 &&       sqlite3StrICmp(zConflict, "abort"   ) != 0 &&       sqlite3StrICmp(zConflict, "fail"    ) != 0 &&       sqlite3StrICmp(zConflict, "ignore"  ) != 0 &&       sqlite3StrICmp(zConflict, "replace" ) != 0 ) {      Tcl_AppendResult(interp, "Error: \"", zConflict,             "\", conflict-algorithm must be one of: rollback, "            "abort, fail, ignore, or replace", 0);      return TCL_ERROR;    }    zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);    if( zSql==0 ){      Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0);      return TCL_ERROR;    }    nByte = strlen(zSql);    rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);    sqlite3_free(zSql);    if( rc ){      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);      nCol = 0;    }else{      nCol = sqlite3_column_count(pStmt);    }    sqlite3_finalize(pStmt);    if( nCol==0 ) {      return TCL_ERROR;    }    zSql = malloc( nByte + 50 + nCol*2 );    if( zSql==0 ) {      Tcl_AppendResult(interp, "Error: can't malloc()", 0);      return TCL_ERROR;    }    sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",         zConflict, zTable);    j = strlen(zSql);    for(i=1; i<nCol; i++){      zSql[j++] = ',';      zSql[j++] = '?';    }    zSql[j++] = ')';    zSql[j] = 0;    rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);    free(zSql);    if( rc ){      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);      sqlite3_finalize(pStmt);      return TCL_ERROR;    }    in = fopen(zFile, "rb");    if( in==0 ){      Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, NULL);      sqlite3_finalize(pStmt);      return TCL_ERROR;    }    azCol = malloc( sizeof(azCol[0])*(nCol+1) );    if( azCol==0 ) {      Tcl_AppendResult(interp, "Error: can't malloc()", 0);      fclose(in);      return TCL_ERROR;    }    (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);    zCommit = "COMMIT";    while( (zLine = local_getline(0, in))!=0 ){      char *z;      i = 0;      lineno++;      azCol[0] = zLine;      for(i=0, z=zLine; *z; z++){        if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){          *z = 0;          i++;          if( i<nCol ){            azCol[i] = &z[nSep];            z += nSep-1;          }        }      }      if( i+1!=nCol ){        char *zErr;        int nErr = strlen(zFile) + 200;        zErr = malloc(nErr);        if( zErr ){          sqlite3_snprintf(nErr, zErr,             "Error: %s line %d: expected %d columns of data but found %d",             zFile, lineno, nCol, i+1);          Tcl_AppendResult(interp, zErr, 0);          free(zErr);        }        zCommit = "ROLLBACK";        break;      }      for(i=0; i<nCol; i++){        /* check for null data, if so, bind as null */        if ((nNull>0 && strcmp(azCol[i], zNull)==0) || strlen(azCol[i])==0) {          sqlite3_bind_null(pStmt, i+1);        }else{          sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);        }      }      sqlite3_step(pStmt);      rc = sqlite3_reset(pStmt);      free(zLine);      if( rc!=SQLITE_OK ){        Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0);        zCommit = "ROLLBACK";        break;      }    }    free(azCol);    fclose(in);    sqlite3_finalize(pStmt);    (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0);    if( zCommit[0] == 'C' ){      /* success, set result as number of lines processed */      pResult = Tcl_GetObjResult(interp);      Tcl_SetIntObj(pResult, lineno);      rc = TCL_OK;    }else{      /* failure, append lineno where failed */      sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);      Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0);      rc = TCL_ERROR;    }    break;  }  /*  **    $db enable_load_extension BOOLEAN  **  ** Turn the extension loading feature on or off.  It if off by  ** default.  */  case DB_ENABLE_LOAD_EXTENSION: {#ifndef SQLITE_OMIT_LOAD_EXTENSION    int onoff;    if( objc!=3 ){      Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN");      return TCL_ERROR;    }    if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){      return TCL_ERROR;    }    sqlite3_enable_load_extension(pDb->db, onoff);    break;#else    Tcl_AppendResult(interp, "extension loading is turned off at compile-time",                     0);    return TCL_ERROR;#endif  }  /*  **    $db errorcode  **  ** Return the numeric error code that was returned by the most recent  ** call to sqlite3_exec().  */  case DB_ERRORCODE: {    Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));    break;  }     /*  **    $db eval $sql ?array? ?{  ...code... }?  **    $db onecolumn $sql  **  ** The SQL statement in $sql is evaluated.  For each row, the values are  ** placed in elements of the array named "array" and ...code... is executed.  ** If "array" and "code" are omitted, then no callback is every invoked.  ** If "array" is an empty string, then the values are placed in variables  ** that have the same name as the fields extracted by the query.  **  ** The onecolumn method is the equivalent of:  **     lindex [$db eval $sql] 0  */  case DB_ONECOLUMN:  case DB_EVAL:  case DB_EXISTS: {    char const *zSql;      /* Next SQL statement to execute */    char const *zLeft;     /* What is left after first stmt in zSql */    sqlite3_stmt *pStmt;   /* Compiled SQL statment */    Tcl_Obj *pArray;       /* Name of array into which results are written */    Tcl_Obj *pScript;      /* Script to run for each result set */    Tcl_Obj **apParm;      /* Parameters that need a Tcl_DecrRefCount() */    int nParm;             /* Number of entries used in apParm[] */    Tcl_Obj *aParm[10];    /* Static space for apParm[] in the common case */    Tcl_Obj *pRet;         /* Value to be returned */    SqlPreparedStmt *pPreStmt;  /* Pointer to a prepared statement */    int rc2;    if( choice==DB_EVAL ){      if( objc<3 || objc>5 ){        Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");        return TCL_ERROR;      }      pRet = Tcl_NewObj();      Tcl_IncrRefCount(pRet);    }else{      if( objc!=3 ){        Tcl_WrongNumArgs(interp, 2, objv, "SQL");        return TCL_ERROR;      }      if( choice==DB_EXISTS ){        pRet = Tcl_NewBooleanObj(0);        Tcl_IncrRefCount(pRet);      }else{        pRet = 0;      }    }    if( objc==3 ){      pArray = pScript = 0;    }else if( objc==4 ){      pArray = 0;      pScript = objv[3];    }else{      pArray = objv[3];      if( Tcl_GetString(pArray)[0]==0 ) pArray = 0;      pScript = objv[4];    }    Tcl_IncrRefCount(objv[2]);    zSql = Tcl_GetStringFromObj(objv[2], 0);    while( rc==TCL_OK && zSql[0] ){      int i;                     /* Loop counter */      int nVar;                  /* Number of bind parameters in the pStmt */      int nCol;                  /* Number of columns in the result set */      Tcl_Obj **apColName = 0;   /* Array of column names */      int len;                   /* String length of zSql */        /* Try to find a SQL statement that has already been compiled and      ** which matches the next sequence of SQL.      */      pStmt = 0;      pPreStmt = pDb->stmtList;      len = strlen(zSql);      if( pPreStmt && sqlite3_expired(pPreStmt->pStmt) ){        flushStmtCache(pDb);        pPreStmt = 0;      }      for(; pPreStmt; pPreStmt=pPreStmt->pNext){        int n = pPreStmt->nSql;        if( len>=n             && memcmp(pPreStmt->zSql, zSql, n)==0            && (zSql[n]==0 || zSql[n-1]==';')        ){          pStmt = pPreStmt->pStmt;          zLeft = &zSql[pPreStmt->nSql];          /* When a prepared statement is found, unlink it from the          ** cache list.  It will later be added back to the beginning          ** of the cache list in order to implement LRU replacement.          */          if( pPreStmt->pPrev ){            pPreStmt->pPrev->pNext = pPreStmt->pNext;          }else{            pDb->stmtList = pPreStmt->pNext;          }          if( pPreStmt->pNext ){            pPreStmt->pNext->pPrev = pPreStmt->pPrev;          }else{            pDb->stmtLast = pPreStmt->pPrev;          }          pDb->nStmt--;          break;        }      }        /* If no prepared statement was found.  Compile the SQL text      */      if( pStmt==0 ){        if( SQLITE_OK!=sqlite3_prepare(pDb->db, zSql, -1, &pStmt, &zLeft) ){          Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));          rc = TCL_ERROR;          break;        }        if( pStmt==0 ){          if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){            /* A compile-time error in the statement            */            Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));            rc = TCL_ERROR;            break;          }else{            /* The statement was a no-op.  Continue to the next statement            ** in the SQL string.            */            zSql = zLeft;            continue;          }        }        assert( pPreStmt==0 );      }      /* Bind values to parameters that begin with $ or :      */        nVar = sqlite3_bind_parameter_count(pStmt);      nParm = 0;      if( nVar>sizeof(aParm)/sizeof(aParm[0]) ){        apParm = (Tcl_Obj**)Tcl_Alloc(nVar*sizeof(apParm[0]));      }else{        apParm = aParm;      }      for(i=1; i<=nVar; i++){        const char *zVar = sqlite3_bind_parameter_name(pStmt, i);        if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){          Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);          if( pVar ){            int n;            u8 *data;            char *zType = pVar->typePtr ? pVar->typePtr->name : "";            char c = zType[0];            if( zVar[0]=='@' ||               (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){              /* Load a BLOB type if the Tcl variable is a bytearray and              ** it has no string representation or the host              ** parameter name begins with "@". */              data = Tcl_GetByteArrayFromObj(pVar, &n);              sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);              Tcl_IncrRefCount(pVar);              apParm[nParm++] = pVar;            }else if( c=='b' && strcmp(zType,"boolean")==0 ){              Tcl_GetIntFromObj(interp, pVar, &n);              sqlite3_bind_int(pStmt, i, n);            }else if( c=='d' && strcmp(zType,"double")==0 ){              double r;              Tcl_GetDoubleFromObj(interp, pVar, &r);              sqlite3_bind_double(pStmt, i, r);            }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||                  (c=='i' && strcmp(zType,"int")==0) ){              Tcl_WideInt v;              Tcl_GetWideIntFromObj(interp, pVar, &v);              sqlite3_bind_int64(pStmt, i, v);            }else{              data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);              sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);              Tcl_IncrRefCount(pVar);              apParm[nParm++] = pVar;            }          }else{            sqlite3_bind_null( pStmt, i );          }        }      }      /* Compute column names */      nCol = sqlite3_column_count(pStmt);      if( pScript ){        apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );        if( apColName==0 ) break;        for(i=0; i<nCol; i++){          apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i));          Tcl_IncrRefCount(apColName[i]);        }      }      /* If results are being stored in an array variable, then create      ** the array(*) entry for that array      */      if( pArray ){        Tcl_Obj *pColList = Tcl_NewObj();        Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);        Tcl_IncrRefCount(pColList);        for(i=0; i<nCol; i++){          Tcl_ListObjAppendElement(interp, pColList, apColName[i]);        }        Tcl_ObjSetVar2(interp, pArray, pStar, pColList,0);        Tcl_DecrRefCount(pColList);        Tcl_DecrRefCount(pStar);      }      /* Execute the SQL      */      while( rc==TCL_OK && pStmt && SQLITE_ROW==sqlite3_step(pStmt) ){        for(i=0; i<nCol; i++){          Tcl_Obj *pVal;                    /* Set pVal to contain the i'th column of this row. */          switch( sqlite3_column_type(pStmt, i) ){            case SQLITE_BLOB: {              int bytes = sqlite3_column_bytes(pStmt, i);              pVal = Tcl_NewByteArrayObj(sqlite3_column_blob(pStmt, i), bytes);              break;            }            case SQLITE_INTEGER: {              sqlite_int64 v = sqlite3_column_int64(pStmt, i);              if( v>=-2147483647 && v<=2147483647 ){                pVal = Tcl_NewIntObj(v);              }else{                pVal = Tcl_NewWideIntObj(v);              }              break;            }            case SQLITE_FLOAT: {              double r = sqlite3_column_double(pStmt, i);              pVal = Tcl_NewDoubleObj(r);              break;            }            case SQLITE_NULL: {              pVal = dbTextToObj(pDb->zNull);              break;            }            default: {              pVal = dbTextToObj((char *)sqlite3_column_text(pStmt, i));              break;            }          }            if( pScript ){            if( pArray==0 ){              Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);            }else{              Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);            }          }else if( choice==DB_ONECOLUMN ){            assert( pRet==0 );            if( pRet==0 ){

⌨️ 快捷键说明

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