/* ** 2005 May 23 ** ** 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. ** ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** SQLITE_SOURCE_ID: 2011-05-19 13:26:54 ed1da510a239ea767a01dc332b667119fa3c908e ** ************************************************************************* */ //#include "sqliteInt.h" /* ** Invoke the 'collation needed' callback to request a collation sequence ** in the encoding enc of name zName, length nName. */ static void callCollNeeded(sqlite3 db, int enc, string zName) { Debug.Assert(db.xCollNeeded == null || db.xCollNeeded16 == null); if (db.xCollNeeded != null) { string zExternal = zName;// sqlite3DbStrDup(db, zName); if (zExternal == null) { return; } db.xCollNeeded(db.pCollNeededArg, db, enc, zExternal); sqlite3DbFree(db, ref zExternal); } #if !SQLITE_OMIT_UTF16 if (db.xCollNeeded16 != null) { string zExternal; sqlite3_value pTmp = sqlite3ValueNew(db); sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); if (zExternal != "") { db.xCollNeeded16(db.pCollNeededArg, db, db.aDbStatic[0].pSchema.enc, zExternal);//(int)ENC(db), zExternal); } sqlite3ValueFree(ref pTmp); } #endif }
/* ** 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. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2 ** ************************************************************************* */ //#include "sqliteInt.h" #if !SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ //static void updateVirtualTable( //Parse pParse, /* The parsing context */ //SrcList pSrc, /* The virtual table to be modified */ //Table pTab, /* The virtual table */ //ExprList pChanges, /* The columns to change in the UPDATE statement */ //Expr pRowidExpr, /* Expression used to recompute the rowid */ //int aXRef, /* Mapping from columns of pTab to entries in pChanges */ //Expr *pWhere, /* WHERE clause of the UPDATE statement */ //int onError /* ON CONFLICT strategy */ //); #endif // * SQLITE_OMIT_VIRTUALTABLE */ /* ** The most recently coded instruction was an OP_Column to retrieve the ** i-th column of table pTab. This routine sets the P4 parameter of the ** OP_Column to the default value, if any. ** ** The default value of a column is specified by a DEFAULT clause in the ** column definition. This was either supplied by the user when the table ** was created, or added later to the table definition by an ALTER TABLE ** command. If the latter, then the row-records in the table btree on disk ** may not contain a value for the column and the default value, taken ** from the P4 parameter of the OP_Column instruction, is returned instead. ** If the former, then all row-records are guaranteed to include a value ** for the column and the P4 value is not required. ** ** Column definitions created by an ALTER TABLE command may only have ** literal default values specified: a number, null or a string. (If a more ** complicated default expression value was provided, it is evaluated ** when the ALTER TABLE is executed and one of the literal values written ** into the sqlite_master table.) ** ** Therefore, the P4 parameter is only required if the default value for ** the column is a literal number, string or null. The sqlite3ValueFromExpr() ** function is capable of transforming these types of expressions into ** sqlite3_value objects. ** ** If parameter iReg is not negative, code an OP_RealAffinity instruction ** on register iReg. This is used when an equivalent integer value is ** stored in place of an 8-byte floating point value in order to save ** space. */ static void sqlite3ColumnDefault(Vdbe v, Table pTab, int i, int iReg) { Debug.Assert(pTab != null); if (null == pTab.pSelect) { sqlite3_value pValue = new sqlite3_value(); int enc = ENC(sqlite3VdbeDb(v)); Column pCol = pTab.aCol[i]; #if SQLITE_DEBUG VdbeComment(v, "%s.%s", pTab.zName, pCol.zName); #endif Debug.Assert(i < pTab.nCol); sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol.pDflt, enc, pCol.affinity, ref pValue); if (pValue != null) { sqlite3VdbeChangeP4(v, -1, pValue, P4_MEM); } #if !SQLITE_OMIT_FLOATING_POINT if (iReg >= 0 && pTab.aCol[i].affinity == SQLITE_AFF_REAL) { sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); } #endif } }
/* ** Implementation of the non-aggregate min() and max() functions */ private static void minmaxFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { int i; int mask; /* 0 for min() or 0xffffffff for max() */ int iBest; CollSeq pColl; Debug.Assert(argc > 1); mask = (int)sqlite3_user_data(context) == 0 ? 0 : -1; pColl = sqlite3GetFuncCollSeq(context); Debug.Assert(pColl != null); Debug.Assert(mask == -1 || mask == 0); testcase(mask == 0); iBest = 0; if (sqlite3_value_type(argv[0]) == SQLITE_NULL) return; for (i = 1; i < argc; i++) { if (sqlite3_value_type(argv[i]) == SQLITE_NULL) return; if ((sqlite3MemCompare(argv[iBest], argv[i], pColl) ^ mask) >= 0) { iBest = i; } } sqlite3_result_value(context, argv[iBest]); }
/* ** 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. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.207 2009/08/08 18:01:08 drh Exp $ ** ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** $Header$ ************************************************************************* */ //#include "sqliteInt.h" #if !SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ //static void updateVirtualTable( //Parse pParse, /* The parsing context */ //SrcList pSrc, /* The virtual table to be modified */ //Table pTab, /* The virtual table */ //ExprList pChanges, /* The columns to change in the UPDATE statement */ //Expr pRowidExpr, /* Expression used to recompute the rowid */ //int aXRef, /* Mapping from columns of pTab to entries in pChanges */ //Expr pWhere /* WHERE clause of the UPDATE statement */ //); #endif // * SQLITE_OMIT_VIRTUALTABLE */ /* ** The most recently coded instruction was an OP_Column to retrieve the ** i-th column of table pTab. This routine sets the P4 parameter of the ** OP_Column to the default value, if any. ** ** The default value of a column is specified by a DEFAULT clause in the ** column definition. This was either supplied by the user when the table ** was created, or added later to the table definition by an ALTER TABLE ** command. If the latter, then the row-records in the table btree on disk ** may not contain a value for the column and the default value, taken ** from the P4 parameter of the OP_Column instruction, is returned instead. ** If the former, then all row-records are guaranteed to include a value ** for the column and the P4 value is not required. ** ** Column definitions created by an ALTER TABLE command may only have ** literal default values specified: a number, null or a string. (If a more ** complicated default expression value was provided, it is evaluated ** when the ALTER TABLE is executed and one of the literal values written ** into the sqlite_master table.) ** ** Therefore, the P4 parameter is only required if the default value for ** the column is a literal number, string or null. The sqlite3ValueFromExpr() ** function is capable of transforming these types of expressions into ** sqlite3_value objects. ** ** If parameter iReg is not negative, code an OP_RealAffinity instruction ** on register iReg. This is used when an equivalent integer value is ** stored in place of an 8-byte floating point value in order to save ** space. */ static void sqlite3ColumnDefault( Vdbe v, Table pTab, int i, int iReg ) { Debug.Assert( pTab != null ); if ( null == pTab.pSelect ) { sqlite3_value pValue = new sqlite3_value(); int enc = ENC( sqlite3VdbeDb( v ) ); Column pCol = pTab.aCol[i]; #if SQLITE_DEBUG VdbeComment( v, "%s.%s", pTab.zName, pCol.zName ); #endif Debug.Assert( i < pTab.nCol ); sqlite3ValueFromExpr( sqlite3VdbeDb( v ), pCol.pDflt, enc, pCol.affinity, ref pValue ); if ( pValue != null ) { sqlite3VdbeChangeP4( v, -1, pValue, P4_MEM ); } #if !SQLITE_OMIT_FLOATING_POINT if ( iReg >= 0 && pTab.aCol[i].affinity == SQLITE_AFF_REAL ) { sqlite3VdbeAddOp1( v, OP_RealAffinity, iReg ); } #endif } }
/* ** 2005 February 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. ** ************************************************************************* ** This file contains C code routines that used to generate VDBE code ** that implements the ALTER TABLE command. ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2 ** ************************************************************************* */ //#include "sqliteInt.h" /* ** The code in this file only exists if we are not omitting the ** ALTER TABLE logic from the build. */ #if !SQLITE_OMIT_ALTERTABLE /* ** This function is used by SQL generated to implement the ** ALTER TABLE command. The first argument is the text of a CREATE TABLE or ** CREATE INDEX command. The second is a table name. The table name in ** the CREATE TABLE or CREATE INDEX statement is replaced with the third ** argument and the result returned. Examples: ** ** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') ** . 'CREATE TABLE def(a, b, c)' ** ** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') ** . 'CREATE INDEX i ON def(a, b, c)' */ static void renameTableFunc( sqlite3_context context, int NotUsed, sqlite3_value[] argv ) { string bResult = sqlite3_value_text( argv[0] ); string zSql = bResult == null ? "" : bResult; string zTableName = sqlite3_value_text( argv[1] ); int token = 0; Token tname = new Token(); int zCsr = 0; int zLoc = 0; int len = 0; string zRet; sqlite3 db = sqlite3_context_db_handle( context ); UNUSED_PARAMETER( NotUsed ); /* The principle used to locate the table name in the CREATE TABLE ** statement is that the table name is the first non-space token that ** is immediately followed by a TK_LP or TK_USING token. */ if ( zSql != "" ) { do { if ( zCsr == zSql.Length ) { /* Ran out of input before finding an opening bracket. Return NULL. */ return; } /* Store the token that zCsr points to in tname. */ zLoc = zCsr; tname.z = zSql.Substring( zCsr );//(char*)zCsr; tname.n = len; /* Advance zCsr to the next token. Store that token type in 'token', ** and its length in 'len' (to be used next iteration of this loop). */ do { zCsr += len; len = ( zCsr == zSql.Length ) ? 1 : sqlite3GetToken( zSql, zCsr, ref token ); } while ( token == TK_SPACE ); Debug.Assert( len > 0 ); } while ( token != TK_LP && token != TK_USING ); zRet = sqlite3MPrintf( db, "%.*s\"%w\"%s", zLoc, zSql.Substring( 0, zLoc ), zTableName, zSql.Substring( zLoc + tname.n ) ); sqlite3_result_text( context, zRet, -1, SQLITE_DYNAMIC ); } }
/* ** The cube() SQL function returns the cube of its input value. */ static void cubeFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { double r = sqlite3_value_double( argv[0] ); sqlite3_result_double( context, r * r * r ); }
/* ** This function generates a string of random characters. Used for ** generating test data. */ static void randStr( sqlite3_context context, int argc, sqlite3_value[] argv ) { string zSrc = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + ".-!,:*^+=_|?/<> "; int iMin, iMax, n, i; i64 r = 0; StringBuilder zBuf = new StringBuilder( 1000 ); /* It used to be possible to call randstr() with any number of arguments, ** but now it is registered with SQLite as requiring exactly 2. */ Debug.Assert( argc == 2 ); iMin = sqlite3_value_int( argv[0] ); if ( iMin < 0 ) iMin = 0; if ( iMin >= zBuf.Capacity ) iMin = zBuf.Capacity - 1; iMax = sqlite3_value_int( argv[1] ); if ( iMax < iMin ) iMax = iMin; if ( iMax >= zBuf.Capacity ) iMax = zBuf.Capacity - 1; n = iMin; if ( iMax > iMin ) { sqlite3_randomness( sizeof( i64 ), ref r ); r &= 0x7fffffff; n += (int)( r % ( iMax + 1 - iMin ) ); } Debug.Assert( n < zBuf.Capacity );//sizeof( zBuf ) ); i64 zRan = 0; for ( i = 0; i < n; i++ ) { sqlite3_randomness( 1, ref zRan ); zBuf.Append( zSrc[(int)( Math.Abs( zRan ) % ( zSrc.Length - 1 ) )] ); } //zBuf[n] = 0; sqlite3_result_text( context, zBuf, n, SQLITE_TRANSIENT ); }
List <string> run_column_name_query(sqlite3 db, string table) { List <string> columnNames = new List <string>(); string sql = "PRAGMA table_info(" + table + ");"; sqlite3_stmt pSelect = new sqlite3_stmt(); int rc; string sDummy = null; rc = Sqlite3.sqlite3_prepare(db, sql, -1, ref pSelect, ref sDummy); if (rc != Sqlite3.SQLITE_OK || null == pSelect) { return(columnNames); } rc = Sqlite3.sqlite3_step(pSelect); while (rc == Sqlite3.SQLITE_ROW) { sqlite3_value val = Sqlite3.sqlite3_column_value(pSelect, 1); columnNames.Add(val.z); rc = Sqlite3.sqlite3_step(pSelect); } Sqlite3.sqlite3_finalize(pSelect); return(columnNames); }
/* ** Implementation of the changes() SQL function. ** ** IMP: R-62073-11209 The changes() SQL function is a wrapper ** around the sqlite3_changes() C/C++ function and hence follows the same ** rules for counting changes. */ private static void changes( sqlite3_context context, int NotUsed, sqlite3_value[] NotUsed2 ) { sqlite3 db = sqlite3_context_db_handle(context); UNUSED_PARAMETER2(NotUsed, NotUsed2); sqlite3_result_int(context, sqlite3_changes(db)); }
/* ** Change the string value of an sqlite3_value object */ private static void sqlite3ValueSetStr( sqlite3_value v, /* Value to be set */ int n, /* Length of string z */ string z, /* Text of the new string */ u8 enc, /* Encoding to use */ dxDel xDel//)(void*) /* Destructor for the string */ ) { if (v != null) sqlite3VdbeMemSetStr(v, z, n, enc, xDel); }
/* ** Return the number of bytes in the sqlite3_value object assuming ** that it uses the encoding "enc" */ private static int sqlite3ValueBytes(sqlite3_value pVal, int enc) { Mem p = (Mem)pVal; if ((p.flags & MEM_Blob) != 0 || sqlite3ValueText(pVal, enc) != null) { if ((p.flags & MEM_Zero) != 0) { return p.n + p.u.nZero; } else { return p.z == null ? p.zBLOB.Length : p.n; } } return 0; }
internal NativeValue(sqlite3_value value) { this.value = value; }
/* This function is only available internally, it is not part of the ** external API. It works in a similar way to sqlite3_value_text(), ** except the data returned is in the encoding specified by the second ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or ** SQLITE_UTF8. ** ** (2006-02-16:) The enc value can be or-ed with SQLITE_UTF16_ALIGNED. ** If that is the case, then the result must be aligned on an even byte ** boundary. */ private static string sqlite3ValueText(sqlite3_value pVal, int enc) { if (pVal == null) return null; Debug.Assert(pVal.db == null || sqlite3_mutex_held(pVal.db.mutex)); Debug.Assert((enc & 3) == (enc & ~SQLITE_UTF16_ALIGNED)); Debug.Assert((pVal.flags & MEM_RowSet) == 0); if ((pVal.flags & MEM_Null) != 0) { return null; } Debug.Assert((MEM_Blob >> 3) == MEM_Str); pVal.flags |= (u16)((pVal.flags & MEM_Blob) >> 3); if ((pVal.flags & MEM_Zero) != 0) sqlite3VdbeMemExpandBlob(pVal); // expandBlob(pVal); if ((pVal.flags & MEM_Str) != 0) { if (sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED) != SQLITE_OK) { return null; // Encoding Error } if ((enc & SQLITE_UTF16_ALIGNED) != 0 && 1 == (1 & (pVal.z[0]))) //1==(1&SQLITE_PTR_TO_INT(pVal.z)) { Debug.Assert((pVal.flags & (MEM_Ephem | MEM_Static)) != 0); if (sqlite3VdbeMemMakeWriteable(pVal) != SQLITE_OK) { return null; } } sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-59893-45467 */ } else { Debug.Assert((pVal.flags & MEM_Blob) == 0); sqlite3VdbeMemStringify(pVal, enc); // assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) ); } Debug.Assert(pVal.enc == (enc & ~SQLITE_UTF16_ALIGNED) || pVal.db == null //|| pVal.db.mallocFailed != 0 ); if (pVal.enc == (enc & ~SQLITE_UTF16_ALIGNED)) { return pVal.z; } else { return null; } }
public static string value_text(this sqlite3_value val) { return(raw.sqlite3_value_text(val)); }
/* ** Try to convert the type of a function argument or a result column ** into a numeric representation. Use either INTEGER or REAL whichever ** is appropriate. But only do the conversion if it is possible without ** loss of information and return the revised type of the argument. */ static int sqlite3_value_numeric_type(sqlite3_value pVal) { Mem pMem = (Mem)pVal; if (pMem.type == SQLITE_TEXT) { applyNumericAffinity(pMem); sqlite3VdbeMemStoreType(pMem); } return pMem.type; }
/* ** Implementation of "GLOB" function on the echo module. Pass ** all arguments to the ::echo_glob_overload procedure of TCL ** and return the result of that procedure as a string. */ static void overloadedGlobFunction( sqlite3_context pContext, int nArg, sqlite3_value[] apArg ) { Tcl_Interp interp = (Interp)sqlite3_user_data( pContext ); TclObject str = null; int i; int rc; TCL.Tcl_DStringInit( out str ); TCL.Tcl_DStringAppendElement( str, "::echo_glob_overload" ); for ( i = 0; i < nArg; i++ ) { TCL.Tcl_DStringAppendElement( str, " " + sqlite3_value_text( apArg[i] ) ); } rc = TCL.Tcl_EvalObjEx( interp, str, 0 );// rc = TCL.Tcl_Eval( interp, TCL.Tcl_DStringValue( ref str ) ); TCL.Tcl_DStringFree( ref str ); if ( rc != 0 ) { sqlite3_result_error( pContext, TCL.Tcl_GetStringResult( interp ), -1 ); } else { sqlite3_result_text( pContext, TCL.Tcl_GetStringResult( interp ), -1, SQLITE_TRANSIENT ); } TCL.Tcl_ResetResult( interp ); }
internal static ISQLiteValue ToSQLiteValue(this sqlite3_value This) => new NativeValue(This);
public static int value_type(this sqlite3_value val) { return(raw.sqlite3_value_type(val)); }
public static byte[] value_blob(this sqlite3_value val) { return(raw.sqlite3_value_blob(val)); }
public static double value_double(this sqlite3_value val) { return(raw.sqlite3_value_double(val)); }
public static long value_int64(this sqlite3_value val) { return(raw.sqlite3_value_int64(val)); }
public static int value_bytes(this sqlite3_value val) { return(raw.sqlite3_value_bytes(val)); }
/* ** Implementation of the like() SQL function. This function implements ** the build-in LIKE operator. The first argument to the function is the ** pattern and the second argument is the string. So, the SQL statements: ** ** A LIKE B ** ** is implemented as like(B,A). ** ** This same function (with a different compareInfo structure) computes ** the GLOB operator. */ private static void likeFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { string zA, zB; u32 escape = 0; int nPat; sqlite3 db = sqlite3_context_db_handle(context); zB = sqlite3_value_text(argv[0]); zA = sqlite3_value_text(argv[1]); /* Limit the length of the LIKE or GLOB pattern to avoid problems ** of deep recursion and N*N behavior in patternCompare(). */ nPat = sqlite3_value_bytes(argv[0]); testcase(nPat == db.aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]); testcase(nPat == db.aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] + 1); if (nPat > db.aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]) { sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); return; } //Debug.Assert( zB == sqlite3_value_text( argv[0] ) ); /* Encoding did not change */ if (argc == 3) { /* The escape character string must consist of a single UTF-8 character. ** Otherwise, return an error. */ string zEsc = sqlite3_value_text(argv[2]); if (zEsc == null) return; if (sqlite3Utf8CharLen(zEsc, -1) != 1) { sqlite3_result_error(context, "ESCAPE expression must be a single character", -1); return; } escape = sqlite3Utf8Read(zEsc, ref zEsc); } if (zA != null && zB != null) { compareInfo pInfo = (compareInfo)sqlite3_user_data(context); #if SQLITE_TEST #if !TCLSH sqlite3_like_count++; #else sqlite3_like_count.iValue++; #endif #endif sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape) ? 1 : 0); } }
/* ** Implementation of the NULLIF(x,y) function. The result is the first ** argument if the arguments are different. The result is NULL if the ** arguments are equal to each other. */ private static void nullifFunc( sqlite3_context context, int NotUsed, sqlite3_value[] argv ) { CollSeq pColl = sqlite3GetFuncCollSeq(context); UNUSED_PARAMETER(NotUsed); if (sqlite3MemCompare(argv[0], argv[1], pColl) != 0) { sqlite3_result_value(context, argv[0]); } }
/* ** Implementation of the last_insert_rowid() SQL function. The return ** value is the same as the sqlite3_last_insert_rowid() API function. */ private static void last_insert_rowid( sqlite3_context context, int NotUsed, sqlite3_value[] NotUsed2 ) { sqlite3 db = sqlite3_context_db_handle(context); UNUSED_PARAMETER2(NotUsed, NotUsed2); /* IMP: R-51513-12026 The last_insert_rowid() SQL function is a ** wrapper around the sqlite3_last_insert_rowid() C/C++ interface ** function. */ sqlite3_result_int64(context, sqlite3_last_insert_rowid(db)); }
public static ReadOnlySpan <byte> value_blob(this sqlite3_value val) { return(raw.sqlite3_value_blob(val)); }
/* ** Implementation of the total_changes() SQL function. The return value is ** the same as the sqlite3_total_changes() API function. */ private static void total_changes( sqlite3_context context, int NotUsed, sqlite3_value[] NotUsed2 ) { sqlite3 db = (sqlite3)sqlite3_context_db_handle(context); UNUSED_PARAMETER2(NotUsed, NotUsed2); /* IMP: R-52756-41993 This function is a wrapper around the ** sqlite3_total_changes() C/C++ interface. */ sqlite3_result_int(context, sqlite3_total_changes(db)); }
/* ** strftime( FORMAT, TIMESTRING, MOD, MOD, ...) ** ** Return a string described by FORMAT. Conversions as follows: ** ** %d day of month ** %f ** fractional seconds SS.SSS ** %H hour 00-24 ** %j day of year 000-366 ** %J ** Julian day number ** %m month 01-12 ** %M minute 00-59 ** %s seconds since 1970-01-01 ** %S seconds 00-59 ** %w day of week 0-6 sunday==0 ** %W week of year 00-53 ** %Y year 0000-9999 ** %% % */ private static void strftimeFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { { DateTime x = new DateTime(); u64 n; int i, j; StringBuilder z; sqlite3 db; string zFmt = sqlite3_value_text(argv[0]); StringBuilder zdtBuf = new StringBuilder(100); sqlite3_value[] argv1 = new sqlite3_value[argc - 1]; for (i = 0; i < argc - 1; i++) { argv[i + 1].CopyTo(ref argv1[i]); } if (String.IsNullOrEmpty(zFmt) || isDate(context, argc - 1, argv1, ref x) != 0) { return; } db = sqlite3_context_db_handle(context); for (i = 0, n = 1; i < zFmt.Length; i++, n++) { if (zFmt[i] == '%') { switch ((char)zFmt[i + 1]) { case 'd': case 'H': case 'm': case 'M': case 'S': case 'W': n++; break; /* fall thru */ case 'w': case '%': break; case 'f': n += 8; break; case 'j': n += 3; break; case 'Y': n += 8; break; case 's': case 'J': n += 50; break; default: return; /* ERROR. return a NULL */ } i++; } } testcase(n == (u64)(zdtBuf.Length - 1)); testcase(n == (u64)zdtBuf.Length); testcase(n == (u64)db.aLimit[SQLITE_LIMIT_LENGTH] + 1); testcase(n == (u64)db.aLimit[SQLITE_LIMIT_LENGTH]); if (n < (u64)zdtBuf.Capacity) { z = zdtBuf; } else if (n > (u64)db.aLimit[SQLITE_LIMIT_LENGTH]) { sqlite3_result_error_toobig(context); return; } else { z = new StringBuilder((int)n); // sqlite3DbMallocRaw( db, n ); //if ( z == 0 ) //{ // sqlite3_result_error_nomem( context ); // return; //} } computeJD(x); computeYMD_HMS(x); for (i = j = 0; i < zFmt.Length; i++) { if (zFmt[i] != '%') { z.Append((char)zFmt[i]); } else { i++; zdtTemp.Length = 0; switch ((char)zFmt[i]) { case 'd': sqlite3_snprintf(3, zdtTemp, "%02d", x.D); z.Append(zdtTemp); j += 2; break; case 'f': { double s = x.s; if (s > 59.999) { s = 59.999; } sqlite3_snprintf(7, zdtTemp, "%06.3f", s); z.Append(zdtTemp); j = sqlite3Strlen30(z); break; } case 'H': sqlite3_snprintf(3, zdtTemp, "%02d", x.h); z.Append(zdtTemp); j += 2; break; case 'W': /* Fall thru */ case 'j': { int nDay; /* Number of days since 1st day of year */ DateTime y = new DateTime(); x.CopyTo(y); y.validJD = 0; y.M = 1; y.D = 1; computeJD(y); nDay = (int)((x.iJD - y.iJD + 43200000) / 86400000); if (zFmt[i] == 'W') { int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ wd = (int)(((x.iJD + 43200000) / 86400000) % 7); sqlite3_snprintf(3, zdtTemp, "%02d", (nDay + 7 - wd) / 7); z.Append(zdtTemp); j += 2; } else { sqlite3_snprintf(4, zdtTemp, "%03d", nDay + 1); z.Append(zdtTemp); j += 3; } break; } case 'J': { sqlite3_snprintf(20, zdtTemp, "%.16g", x.iJD / 86400000.0); z.Append(zdtTemp); j = sqlite3Strlen30(z); break; } case 'm': sqlite3_snprintf(3, zdtTemp, "%02d", x.M); z.Append(zdtTemp); j += 2; break; case 'M': sqlite3_snprintf(3, zdtTemp, "%02d", x.m); z.Append(zdtTemp); j += 2; break; case 's': { sqlite3_snprintf(30, zdtTemp, "%lld", (i64)(x.iJD / 1000 - 21086676 * (i64)10000)); z.Append(zdtTemp); j = sqlite3Strlen30(z); break; } case 'S': sqlite3_snprintf(3, zdtTemp, "%02d", (int)x.s); z.Append(zdtTemp); j += 2; break; case 'w': { z.Append((((x.iJD + 129600000) / 86400000) % 7)); break; } case 'Y': { sqlite3_snprintf(5, zdtTemp, "%04d", x.Y); z.Append(zdtTemp); j = sqlite3Strlen30(z); break; } default: z.Append('%'); break; } } } //z[j] = 0; sqlite3_result_text(context, z, -1, z == zdtBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC); } }
/* ** Return the type of the argument. */ private static void typeofFunc( sqlite3_context context, int NotUsed, sqlite3_value[] argv ) { string z = ""; UNUSED_PARAMETER(NotUsed); switch (sqlite3_value_type(argv[0])) { case SQLITE_INTEGER: z = "integer"; break; case SQLITE_TEXT: z = "text"; break; case SQLITE_FLOAT: z = "real"; break; case SQLITE_BLOB: z = "blob"; break; default: z = "null"; break; } sqlite3_result_text(context, z, -1, SQLITE_STATIC); }
/* ** Implementation of the TRIM(), LTRIM(), and RTRIM() functions. ** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both. */ private static void trimFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { string zIn; /* Input string */ string zCharSet; /* Set of characters to trim */ int nIn; /* Number of bytes in input */ int izIn = 0; /* C# string pointer */ int flags; /* 1: trimleft 2: trimright 3: trim */ int i; /* Loop counter */ int[] aLen = null; /* Length of each character in zCharSet */ byte[][] azChar = null; /* Individual characters in zCharSet */ int nChar = 0; /* Number of characters in zCharSet */ byte[] zBytes = null; byte[] zBlob = null; if (sqlite3_value_type(argv[0]) == SQLITE_NULL) { return; } zIn = sqlite3_value_text(argv[0]); if (zIn == null) return; nIn = sqlite3_value_bytes(argv[0]); zBlob = sqlite3_value_blob(argv[0]); //Debug.Assert( zIn == sqlite3_value_text( argv[0] ) ); if (argc == 1) { int[] lenOne = new int[] { 1 }; byte[] azOne = new byte[] { (u8)' ' };//static unsigned char * const azOne[] = { (u8*)" " }; nChar = 1; aLen = lenOne; azChar = new byte[1][]; azChar[0] = azOne; zCharSet = null; } else if ((zCharSet = sqlite3_value_text(argv[1])) == null) { return; } else { if ((zBytes = sqlite3_value_blob(argv[1])) != null) { int iz = 0; for (nChar = 0; iz < zBytes.Length; nChar++) { SQLITE_SKIP_UTF8(zBytes, ref iz); } if (nChar > 0) { azChar = new byte[nChar][];//contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1)); if (azChar == null) { return; } aLen = new int[nChar]; int iz0 = 0; int iz1 = 0; for (int ii = 0; ii < nChar; ii++) { SQLITE_SKIP_UTF8(zBytes, ref iz1); aLen[ii] = iz1 - iz0; azChar[ii] = new byte[aLen[ii]]; Buffer.BlockCopy(zBytes, iz0, azChar[ii], 0, azChar[ii].Length); iz0 = iz1; } } } } if (nChar > 0) { flags = (int)sqlite3_user_data(context); // flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context)); if ((flags & 1) != 0) { while (nIn > 0) { int len = 0; for (i = 0; i < nChar; i++) { len = aLen[i]; if (len <= nIn && memcmp(zBlob, izIn, azChar[i], len) == 0) break; } if (i >= nChar) break; izIn += len; nIn -= len; } } if ((flags & 2) != 0) { while (nIn > 0) { int len = 0; for (i = 0; i < nChar; i++) { len = aLen[i]; if (len <= nIn && memcmp(zBlob, izIn + nIn - len, azChar[i], len) == 0) break; } if (i >= nChar) break; nIn -= len; } } if (zCharSet != null) { //sqlite3_free( ref azChar ); } } StringBuilder sb = new StringBuilder(nIn); for (i = 0; i < nIn; i++) sb.Append((char)zBlob[izIn + i]); sqlite3_result_text(context, sb, nIn, SQLITE_TRANSIENT); }
/* ** This function is called after an "ALTER TABLE ... ADD" statement ** has been parsed. Argument pColDef contains the text of the new ** column definition. ** ** The Table structure pParse.pNewTable was extended to include ** the new column during parsing. */ static void sqlite3AlterFinishAddColumn(Parse pParse, Token pColDef) { Table pNew; /* Copy of pParse.pNewTable */ Table pTab; /* Table being altered */ int iDb; /* Database number */ string zDb; /* Database name */ string zTab; /* Table name */ string zCol; /* Null-terminated column definition */ Column pCol; /* The new column */ Expr pDflt; /* Default value for the new column */ sqlite3 db; /* The database connection; */ db = pParse.db; if (pParse.nErr != 0 /*|| db.mallocFailed != 0 */) { return; } pNew = pParse.pNewTable; Debug.Assert(pNew != null); Debug.Assert(sqlite3BtreeHoldsAllMutexes(db)); iDb = sqlite3SchemaToIndex(db, pNew.pSchema); zDb = db.aDb[iDb].zName; zTab = pNew.zName.Substring(16);// zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ pCol = pNew.aCol[pNew.nCol - 1]; pDflt = pCol.pDflt; pTab = sqlite3FindTable(db, zTab, zDb); Debug.Assert(pTab != null); #if !SQLITE_OMIT_AUTHORIZATION /* Invoke the authorization callback. */ if (sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab.zName, 0)) { return; } #endif /* If the default value for the new column was specified with a ** literal NULL, then set pDflt to 0. This simplifies checking ** for an SQL NULL default below. */ if (pDflt != null && pDflt.op == TK_NULL) { pDflt = null; } /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. ** If there is a NOT NULL constraint, then the default value for the ** column must not be NULL. */ if (pCol.isPrimKey != 0) { sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); return; } if (pNew.pIndex != null) { sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); return; } if ((db.flags & SQLITE_ForeignKeys) != 0 && pNew.pFKey != null && pDflt != null) { sqlite3ErrorMsg(pParse, "Cannot add a REFERENCES column with non-NULL default value"); return; } if (pCol.notNull != 0 && pDflt == null) { sqlite3ErrorMsg(pParse, "Cannot add a NOT NULL column with default value NULL"); return; } /* Ensure the default expression is something that sqlite3ValueFromExpr() ** can handle (i.e. not CURRENT_TIME etc.) */ if (pDflt != null) { sqlite3_value pVal = null; if (sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, ref pVal) != 0) { // db.mallocFailed = 1; return; } if (pVal == null) { sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); return; } sqlite3ValueFree(ref pVal); } /* Modify the CREATE TABLE statement. */ zCol = pColDef.z.Substring(0, pColDef.n).Replace(";", " ").Trim();//sqlite3DbStrNDup(db, (char*)pColDef.z, pColDef.n); if (zCol != null) { // char zEnd = zCol[pColDef.n-1]; int savedDbFlags = db.flags; // while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){ // zEnd-- = '\0'; // } db.flags |= SQLITE_PreferBuiltin; sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " + "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " + "WHERE type = 'table' AND name = %Q", zDb, SCHEMA_TABLE(iDb), pNew.addColOffset, zCol, pNew.addColOffset + 1, zTab ); sqlite3DbFree(db, ref zCol); db.flags = savedDbFlags; } /* If the default value of the new column is NULL, then set the file ** format to 2. If the default value of the new column is not NULL, ** the file format becomes 3. */ sqlite3MinimumFileFormat(pParse, iDb, pDflt != null ? 3 : 2); /* Reload the schema of the modified table. */ reloadTableSchema(pParse, pTab, pTab.zName); }
/* IMP: R-25361-16150 This function is omitted from SQLite by default. It ** is only available if the SQLITE_SOUNDEX compile-time option is used ** when SQLite is built. */ #if SQLITE_SOUNDEX /* ** Compute the soundex encoding of a word. ** ** IMP: R-59782-00072 The soundex(X) function returns a string that is the ** soundex encoding of the string X. */ static void soundexFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { Debug.Assert(false); // TODO -- func_c char zResult[8];
/* ** Exported version of applyAffinity(). This one works on sqlite3_value*, ** not the internal Mem type. */ static void sqlite3ValueApplyAffinity( sqlite3_value pVal, char affinity, int enc ) { applyAffinity((Mem)pVal, affinity, enc); }
/* ** Implementation of the abs() function. ** ** IMP: R-23979-26855 The abs(X) function returns the absolute value of ** the numeric argument X. */ private static void absFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { Debug.Assert(argc == 1); UNUSED_PARAMETER(argc); switch (sqlite3_value_type(argv[0])) { case SQLITE_INTEGER: { i64 iVal = sqlite3_value_int64(argv[0]); if (iVal < 0) { if ((iVal << 1) == 0) { /* IMP: R-35460-15084 If X is the integer -9223372036854775807 then ** abs(X) throws an integer overflow error since there is no ** equivalent positive 64-bit two complement value. */ sqlite3_result_error(context, "integer overflow", -1); return; } iVal = -iVal; } sqlite3_result_int64(context, iVal); break; } case SQLITE_NULL: { /* IMP: R-37434-19929 Abs(X) returns NULL if X is NULL. */ sqlite3_result_null(context); break; } default: { /* Because sqlite3_value_double() returns 0.0 if the argument is not ** something that can be converted into a number, we have: ** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that ** cannot be converted to a numeric value. */ double rVal = sqlite3_value_double(argv[0]); if (rVal < 0) rVal = -rVal; sqlite3_result_double(context, rVal); break; } } }
/* ** Implementation of the substr() function. ** ** substr(x,p1,p2) returns p2 characters of x[] beginning with p1. ** p1 is 1-indexed. So substr(x,1,1) returns the first character ** of x. If x is text, then we actually count UTF-8 characters. ** If x is a blob, then we count bytes. ** ** If p1 is negative, then we begin abs(p1) from the end of x[]. ** ** If p2 is negative, return the p2 characters preceeding p1. */ private static void substrFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { string z = ""; byte[] zBLOB = null; string z2; int len; int p0type; int p1, p2; int negP2 = 0; Debug.Assert(argc == 3 || argc == 2); if (sqlite3_value_type(argv[1]) == SQLITE_NULL || (argc == 3 && sqlite3_value_type(argv[2]) == SQLITE_NULL) ) { return; } p0type = sqlite3_value_type(argv[0]); p1 = sqlite3_value_int(argv[1]); if (p0type == SQLITE_BLOB) { len = sqlite3_value_bytes(argv[0]); zBLOB = argv[0].zBLOB; if (zBLOB == null) return; Debug.Assert(len == zBLOB.Length); } else { z = sqlite3_value_text(argv[0]); if (String.IsNullOrEmpty(z)) return; len = 0; if (p1 < 0) { len = z.Length; //for ( z2 = z ; z2 != "" ; len++ ) //{ // SQLITE_SKIP_UTF8( ref z2 ); //} } } if (argc == 3) { p2 = sqlite3_value_int(argv[2]); if (p2 < 0) { p2 = -p2; negP2 = 1; } } else { p2 = (sqlite3_context_db_handle(context)).aLimit[SQLITE_LIMIT_LENGTH]; } if (p1 < 0) { p1 += len; if (p1 < 0) { p2 += p1; if (p2 < 0) p2 = 0; p1 = 0; } } else if (p1 > 0) { p1--; } else if (p2 > 0) { p2--; } if (negP2 != 0) { p1 -= p2; if (p1 < 0) { p2 += p1; p1 = 0; } } Debug.Assert(p1 >= 0 && p2 >= 0); if (p0type != SQLITE_BLOB) { //while ( z != "" && p1 != 0 ) //{ // SQLITE_SKIP_UTF8( ref z ); // p1--; //} //for ( z2 = z ; z2 != "" && p2 != 0 ; p2-- ) //{ // SQLITE_SKIP_UTF8( ref z2 ); //} sqlite3_result_text(context, z, p1, p2 <= z.Length - p1 ? p2 : z.Length - p1, SQLITE_TRANSIENT); } else { if (p1 + p2 > len) { p2 = len - p1; if (p2 < 0) p2 = 0; } StringBuilder sb = new StringBuilder(zBLOB.Length); if (zBLOB.Length == 0 || p1 > zBLOB.Length) sb.Length = 0; else { for (int i = p1; i < p1 + p2; i++) { sb.Append((char)zBLOB[i]); } } sqlite3_result_blob(context, sb.ToString(), (int)p2, SQLITE_TRANSIENT); } }
/* ** Implementation of the round() function */ #if !SQLITE_OMIT_FLOATING_POINT private static void roundFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { int n = 0; double r; string zBuf = ""; Debug.Assert(argc == 1 || argc == 2); if (argc == 2) { if (SQLITE_NULL == sqlite3_value_type(argv[1])) return; n = sqlite3_value_int(argv[1]); if (n > 30) n = 30; if (n < 0) n = 0; } if (sqlite3_value_type(argv[0]) == SQLITE_NULL) return; r = sqlite3_value_double(argv[0]); /* If Y==0 and X will fit in a 64-bit int, ** handle the rounding directly, ** otherwise use printf. */ if (n == 0 && r >= 0 && r < LARGEST_INT64 - 1) { r = (double)((sqlite_int64)(r + 0.5)); } else if (n == 0 && r < 0 && (-r) < LARGEST_INT64 - 1) { r = -(double)((sqlite_int64)((-r) + 0.5)); } else { zBuf = sqlite3_mprintf("%.*f", n, r); if (zBuf == null) { sqlite3_result_error_nomem(context); return; } sqlite3AtoF(zBuf, ref r, sqlite3Strlen30(zBuf), SQLITE_UTF8); //sqlite3_free( ref zBuf ); } sqlite3_result_double(context, r); }
/* ** Create a new sqlite3_value object, containing the value of pExpr. ** ** This only works for very simple expressions that consist of one constant ** token (i.e. "5", "5.1", "'a string'"). If the expression can ** be converted directly into a value, then the value is allocated and ** a pointer written to ppVal. The caller is responsible for deallocating ** the value by passing it to sqlite3ValueFree() later on. If the expression ** cannot be converted to a value, then ppVal is set to NULL. */ private static int sqlite3ValueFromExpr( sqlite3 db, /* The database connection */ Expr pExpr, /* The expression to evaluate */ int enc, /* Encoding to use */ char affinity, /* Affinity to use */ ref sqlite3_value ppVal /* Write the new value here */ ) { int op; string zVal = ""; sqlite3_value pVal = null; int negInt = 1; string zNeg = ""; if (pExpr == null) { ppVal = null; return SQLITE_OK; } op = pExpr.op; /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT2. ** The ifdef here is to enable us to achieve 100% branch test coverage even ** when SQLITE_ENABLE_STAT2 is omitted. */ #if SQLITE_ENABLE_STAT2 if ( op == TK_REGISTER ) op = pExpr.op2; #else if (NEVER(op == TK_REGISTER)) op = pExpr.op2; #endif /* Handle negative integers in a single step. This is needed in the ** case when the value is -9223372036854775808. */ if (op == TK_UMINUS && (pExpr.pLeft.op == TK_INTEGER || pExpr.pLeft.op == TK_FLOAT)) { pExpr = pExpr.pLeft; op = pExpr.op; negInt = -1; zNeg = "-"; } if (op == TK_STRING || op == TK_FLOAT || op == TK_INTEGER) { pVal = sqlite3ValueNew(db); if (pVal == null) goto no_mem; if (ExprHasProperty(pExpr, EP_IntValue)) { sqlite3VdbeMemSetInt64(pVal, (i64)pExpr.u.iValue * negInt); } else { zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr.u.zToken); //if ( zVal == null ) goto no_mem; sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); if (op == TK_FLOAT) pVal.type = SQLITE_FLOAT; } if ((op == TK_INTEGER || op == TK_FLOAT) && affinity == SQLITE_AFF_NONE) { sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); } else { sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); } if ((pVal.flags & (MEM_Int | MEM_Real)) != 0) pVal.flags = (ushort)(pVal.flags & ~MEM_Str); if (enc != SQLITE_UTF8) { sqlite3VdbeChangeEncoding(pVal, enc); } } if (enc != SQLITE_UTF8) { sqlite3VdbeChangeEncoding(pVal, enc); } else if (op == TK_UMINUS) { /* This branch happens for multiple negative signs. Ex: -(-5) */ if (SQLITE_OK == sqlite3ValueFromExpr(db, pExpr.pLeft, enc, affinity, ref pVal)) { sqlite3VdbeMemNumerify(pVal); if (pVal.u.i == SMALLEST_INT64) { pVal.flags &= MEM_Int; pVal.flags |= MEM_Real; pVal.r = (double)LARGEST_INT64; } else { pVal.u.i = -pVal.u.i; } pVal.r = -pVal.r; sqlite3ValueApplyAffinity(pVal, affinity, enc); } } else if (op == TK_NULL) { pVal = sqlite3ValueNew(db); if (pVal == null) goto no_mem; } #if !SQLITE_OMIT_BLOB_LITERAL else if (op == TK_BLOB) { int nVal; Debug.Assert(pExpr.u.zToken[0] == 'x' || pExpr.u.zToken[0] == 'X'); Debug.Assert(pExpr.u.zToken[1] == '\''); pVal = sqlite3ValueNew(db); if (null == pVal) goto no_mem; zVal = pExpr.u.zToken.Substring(2); nVal = sqlite3Strlen30(zVal) - 1; Debug.Assert(zVal[nVal] == '\''); byte[] blob = sqlite3HexToBlob(db, zVal, nVal); sqlite3VdbeMemSetStr(pVal, Encoding.UTF8.GetString(blob, 0, blob.Length), nVal / 2, 0, SQLITE_DYNAMIC); } #endif if (pVal != null) { sqlite3VdbeMemStoreType(pVal); } ppVal = pVal; return SQLITE_OK; no_mem: //db.mallocFailed = 1; sqlite3DbFree(db, ref zVal); pVal = null;// sqlite3ValueFree(pVal); ppVal = null; return SQLITE_NOMEM; }
private static void lowerFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { string z1; string z2; int i, n; UNUSED_PARAMETER(argc); z2 = sqlite3_value_text(argv[0]); n = sqlite3_value_bytes(argv[0]); /* Verify that the call to _bytes() does not invalidate the _text() pointer */ //Debug.Assert( z2 == sqlite3_value_text( argv[0] ) ); if (z2 != null) { //z1 = contextMalloc(context, ((i64)n)+1); //if ( z1 ) //{ // memcpy( z1, z2, n + 1 ); // for ( i = 0 ; z1[i] ; i++ ) // { // z1[i] = (char)sqlite3Tolower( z1[i] ); // } sqlite3_result_text(context, z2.Length == 0 ? "" : z2.Substring(0, n).ToLower(), -1, null);//sqlite3_free ); //} } }
/* ** Free an sqlite3_value object */ private static void sqlite3ValueFree(ref sqlite3_value v) { if (v == null) return; sqlite3VdbeMemRelease(v); sqlite3DbFree(v.db, ref v); }
/* ** The COALESCE() and IFNULL() functions used to be implemented as shown ** here. But now they are implemented as VDBE code so that unused arguments ** do not have to be computed. This legacy implementation is retained as ** comment. */ /* ** Implementation of the IFNULL(), NVL(), and COALESCE() functions. ** All three do the same thing. They return the first non-NULL ** argument. */ static void ifnullFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) { int i; for ( i = 0 ; i < argc ; i++ ) { if ( SQLITE_NULL != sqlite3_value_type( argv[i] ) ) { sqlite3_result_value( context, argv[i] ); break; } } }
public DataSet GetDBTables() { DataSet fredDs = new DataSet("FRED"); List <string> tables = run_table_names_query(pDb); int rc = 0; foreach (string table in tables) { bool firstRun = true; List <string> names = new List <string>(); List <string> arrRows = new List <string>(); List <string> colNames = run_column_name_query(pDb, table); string zSql = "SELECT * from " + table + ";"; sqlite3_stmt pSelect = new sqlite3_stmt(); string sDummy = null; rc = Sqlite3.sqlite3_prepare(pDb, zSql, -1, ref pSelect, ref sDummy); if (rc != Sqlite3.SQLITE_OK || null == pSelect) { continue; } rc = Sqlite3.sqlite3_step(pSelect); DataTable dt = new DataTable(table); while (rc == Sqlite3.SQLITE_ROW) { //Get the data in the cell int total = Sqlite3.sqlite3_column_count(pSelect); DataRow dr = dt.NewRow(); List <string> values = new List <string>(); for (int i = 0; i < total; i++) { int valInt = 0; string value = ""; sqlite3_value val = Sqlite3.sqlite3_column_value(pSelect, i); if (val.type == 1) { valInt = Sqlite3.sqlite3_column_int(pSelect, i); value = valInt.ToString(); } else { value = val.z; } values.Add(value); if (firstRun) { string name = Sqlite3.sqlite3_column_name(pSelect, i); if (name == null) { continue; } names.Add(name); dt.Columns.Add(name); } } rc = Sqlite3.sqlite3_step(pSelect); firstRun = false; for (int i = 0; i < names.Count && i < values.Count; i++) { dr[names[i]] = values[i]; } dt.Rows.Add(dr); } Sqlite3.sqlite3_finalize(pSelect); fredDs.Tables.Add(dt); } Sqlite3.sqlite3_close(pDb); return(fredDs); }
//#define ifnullFunc versionFunc /* Substitute function - never called */ /* ** Implementation of random(). Return a random integer. */ private static void randomFunc( sqlite3_context context, int NotUsed, sqlite3_value[] NotUsed2 ) { sqlite_int64 r = 0; UNUSED_PARAMETER2(NotUsed, NotUsed2); sqlite3_randomness(sizeof(sqlite_int64), ref r); if (r < 0) { /* We need to prevent a random number of 0x8000000000000000 ** (or -9223372036854775808) since when you do abs() of that ** number of you get the same value back again. To do this ** in a way that is testable, mask the sign bit off of negative ** values, resulting in a positive value. Then take the ** 2s complement of that positive value. The end result can ** therefore be no less than -9223372036854775807. */ r = -(r ^ (((sqlite3_int64)1) << 63)); } sqlite3_result_int64(context, r); }
/* ** The xUpdate method for echo module virtual tables. ** ** apData[0] apData[1] apData[2..] ** ** INTEGER DELETE ** ** INTEGER NULL (nCol args) UPDATE (do not set rowid) ** INTEGER INTEGER (nCol args) UPDATE (with SET rowid = <arg1>) ** ** NULL NULL (nCol args) INSERT INTO (automatic rowid value) ** NULL INTEGER (nCol args) INSERT (incl. rowid value) ** */ static int echoUpdate( sqlite3_vtab vtab, int nData, sqlite3_value[] apData, out sqlite_int64 pRowid ) { echo_vtab pVtab = (echo_vtab)vtab; sqlite3 db = pVtab.db; int rc = SQLITE_OK; pRowid = 0; sqlite3_stmt pStmt = null; string z = ""; /* SQL statement to execute */ int bindArgZero = 0; /* True to bind apData[0] to sql var no. nData */ int bindArgOne = 0; /* True to bind apData[1] to sql var no. 1 */ int i; /* Counter variable used by for loops */ Debug.Assert( nData == pVtab.nCol + 2 || nData == 1 ); /* Ticket #3083 - make sure we always start a transaction prior to ** making any changes to a virtual table */ Debug.Assert( pVtab.inTransaction != 0 ); if ( simulateVtabError( pVtab, "xUpdate" ) != 0 ) { return SQLITE_ERROR; } /* If apData[0] is an integer and nData>1 then do an UPDATE */ if ( nData > 1 && sqlite3_value_type( apData[0] ) == SQLITE_INTEGER ) { string zSep = " SET"; z = sqlite3_mprintf( "UPDATE %Q", pVtab.zTableName ); //if ( null == z ) //{ // rc = SQLITE_NOMEM; //} bindArgOne = ( apData[1] != null && sqlite3_value_type( apData[1] ) == SQLITE_INTEGER )?1:0; bindArgZero = 1; if ( bindArgOne != 0 ) { string_concat( ref z, " SET rowid=?1 ", 0, ref rc ); zSep = ","; } for ( i = 2; i < nData; i++ ) { if ( apData[i] == null ) continue; string_concat( ref z, sqlite3_mprintf( "%s %Q=?%d", zSep, pVtab.aCol[i - 2], i ), 1, ref rc ); zSep = ","; } string_concat( ref z, sqlite3_mprintf( " WHERE rowid=?%d", nData ), 1, ref rc ); } /* If apData[0] is an integer and nData==1 then do a DELETE */ else if ( nData == 1 && sqlite3_value_type( apData[0] ) == SQLITE_INTEGER ) { z = sqlite3_mprintf( "DELETE FROM %Q WHERE rowid = ?1", pVtab.zTableName ); //if ( null == z ) //{ // rc = SQLITE_NOMEM; //} bindArgZero = 1; } /* If the first argument is NULL and there are more than two args, INSERT */ else if ( nData > 2 && sqlite3_value_type( apData[0] ) == SQLITE_NULL ) { int ii; string zInsert = ""; string zValues = ""; zInsert = sqlite3_mprintf( "INSERT INTO %Q (", pVtab.zTableName ); //if ( null == zInsert ) //{ // rc = SQLITE_NOMEM; //} if ( sqlite3_value_type( apData[1] ) == SQLITE_INTEGER ) { bindArgOne = 1; zValues = sqlite3_mprintf( "?" ); string_concat( ref zInsert, "rowid", 0, ref rc ); } Debug.Assert( ( pVtab.nCol + 2 ) == nData ); for ( ii = 2; ii < nData; ii++ ) { string_concat( ref zInsert, sqlite3_mprintf( "%s%Q", !String.IsNullOrEmpty(zValues) ? ", " : "", pVtab.aCol[ii - 2] ), 1, ref rc ); string_concat( ref zValues, sqlite3_mprintf( "%s?%d", !String.IsNullOrEmpty( zValues ) ? ", " : "", ii ), 1, ref rc ); } string_concat( ref z, zInsert, 1, ref rc ); string_concat( ref z, ") VALUES(", 0, ref rc ); string_concat( ref z, zValues, 1, ref rc ); string_concat( ref z, ")", 0, ref rc ); } /* Anything else is an error */ else { Debug.Assert( false ); return SQLITE_ERROR; } if ( rc == SQLITE_OK ) { rc = sqlite3_prepare( db, z, -1, ref pStmt, 0 ); } Debug.Assert( rc != SQLITE_OK || pStmt != null ); //sqlite3_free(z); if ( rc == SQLITE_OK ) { if ( bindArgZero != 0 ) { sqlite3_bind_value( pStmt, nData, apData[0] ); } if ( bindArgOne != 0 ) { sqlite3_bind_value( pStmt, 1, apData[1] ); } for ( i = 2; i < nData && rc == SQLITE_OK; i++ ) { if ( apData[i] != null ) rc = sqlite3_bind_value( pStmt, i, apData[i] ); } if ( rc == SQLITE_OK ) { sqlite3_step( pStmt ); rc = sqlite3_finalize( pStmt ); } else { sqlite3_finalize( pStmt ); } } if (/* pRowid != 0 && */ rc == SQLITE_OK ) { pRowid = sqlite3_last_insert_rowid( db ); } if ( rc != SQLITE_OK ) { vtab.zErrMsg = sqlite3_mprintf( "echo-vtab-error: %s", sqlite3_errmsg( db ) ); } return rc; }
/* ** Implementation of randomblob(N). Return a random blob ** that is N bytes long. */ private static void randomBlob( sqlite3_context context, int argc, sqlite3_value[] argv ) { int n; char[] p; Debug.Assert(argc == 1); UNUSED_PARAMETER(argc); n = sqlite3_value_int(argv[0]); if (n < 1) { n = 1; } if (n > sqlite3_context_db_handle(context).aLimit[SQLITE_LIMIT_LENGTH]) { sqlite3_result_error_toobig(context); p = null; } else { p = new char[n]; //contextMalloc( context, n ); } if (p != null) { i64 _p = 0; for (int i = 0; i < n; i++) { sqlite3_randomness(sizeof(u8), ref _p); p[i] = (char)(_p & 0x7F); } sqlite3_result_blob(context, new string(p), n, null);//sqlite3_free ); } }
/* ** Echo virtual table module xFilter method. */ static int echoFilter( sqlite3_vtab_cursor pVtabCursor, int idxNum, string idxStr, int argc, sqlite3_value[] argv ) { int rc; int i; echo_cursor pCur = (echo_cursor)pVtabCursor; echo_vtab pVtab = (echo_vtab)pVtabCursor.pVtab; sqlite3 db = pVtab.db; if ( simulateVtabError( pVtab, "xFilter" ) != 0 ) { return SQLITE_ERROR; } /* Check that idxNum matches idxStr */ Debug.Assert( idxNum == hashString( idxStr ) ); /* Log arguments to the ::echo_module Tcl variable */ appendToEchoModule( pVtab.interp, "xFilter" ); appendToEchoModule( pVtab.interp, idxStr ); for ( i = 0; i < argc; i++ ) { appendToEchoModule( pVtab.interp, sqlite3_value_text( argv[i] ) ); } sqlite3_finalize( pCur.pStmt ); pCur.pStmt = null; /* Prepare the SQL statement created by echoBestIndex and bind the ** runtime parameters passed to this function to it. */ rc = sqlite3_prepare( db, idxStr, -1, ref pCur.pStmt, 0 ); Debug.Assert( pCur.pStmt != null || rc != SQLITE_OK ); for ( i = 0; rc == SQLITE_OK && i < argc; i++ ) { rc = sqlite3_bind_value( pCur.pStmt, i + 1, argv[i] ); } /* If everything was successful, advance to the first row of the scan */ if ( rc == SQLITE_OK ) { rc = echoNext( pVtabCursor ); } return rc; }
public static int value_int(this sqlite3_value val) { return raw.sqlite3_value_int(val); }