/*
 ** 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 );
 }
示例#2
0
        /// <summary>
        /// This C function implements an SQL user function that is used by SQL code
        /// generated by the ALTER TABLE ... RENAME command to modify the definition
        /// of any foreign key constraints that use the table being renamed as the 
        /// parent table. It is passed three arguments:
        ///
        ///   1) The complete text of the CREATE TABLE statement being modified,
        ///   2) The old name of the table being renamed, and
        ///   3) The new name of the table being renamed.
        ///
        /// It returns the new CREATE TABLE statement. For example:
        ///
        ///   sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3')
        ///       -> 'CREATE TABLE t1(a REFERENCES t3)'
        /// </summary>
        static void renameParentFunc(
		  sqlite3_context context,
		  int NotUsed,
		  sqlite3_value[] argv
		)
        {
            sqlite3 db = sqlite3_context_db_handle(context);
            string zOutput = "";
            string zResult;
            string zInput = sqlite3_value_text(argv[0]);
            string zOld = sqlite3_value_text(argv[1]);
            string zNew = sqlite3_value_text(argv[2]);

            int zIdx;         /* Pointer to token */
            int zLeft = 0;    /* Pointer to remainder of String */
            int n = 0;        /* Length of token z */
            int token = 0;    /* Type of token */

            UNUSED_PARAMETER(NotUsed);
            for (zIdx = 0; zIdx < zInput.Length; zIdx += n)//z=zInput; *z; z=z+n)
            {
                n = sqlite3GetToken(zInput, zIdx, ref token);
                if (token == TK_REFERENCES)
                {
                    string zParent;
                    do
                    {
                        zIdx += n;
                        n = sqlite3GetToken(zInput, zIdx, ref token);
                    } while (token == TK_SPACE);

                    zParent = zIdx + n < zInput.Length ? zInput.Substring(zIdx, n) : "";//sqlite3DbStrNDup(db, zIdx, n);
                    if (String.IsNullOrEmpty(zParent))
                        break;
                    sqlite3Dequote(ref zParent);
                    if (zOld.Equals(zParent, StringComparison.InvariantCultureIgnoreCase))
                    {
                        string zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"",
                            zOutput, zIdx - zLeft, zInput.Substring(zLeft), zNew
                        );
                        sqlite3DbFree(db, ref zOutput);
                        zOutput = zOut;
                        zIdx += n;// zInput = &z[n];
                        zLeft = zIdx;
                    }
                    sqlite3DbFree(db, ref zParent);
                }
            }

            zResult = sqlite3MPrintf(db, "%s%s", zOutput, zInput.Substring(zLeft));
            sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC);
            sqlite3DbFree(db, ref zOutput);
        }
示例#3
0
 /*
 ** Implementation of the abs() function.
 **
 ** IMP: R-23979-26855 The abs(X) function returns the absolute value of
 ** the numeric argument X.
 */
 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;
       }
       }
 }
示例#4
0
 /*
 ** Implementation of randomblob(N).  Return a random blob
 ** that is N bytes long.
 */
 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;
       }
       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 );
       }
 }
示例#5
0
 //#define ifnullFunc versionFunc   /* Substitute function - never called */
 /*
 ** Implementation of random().  Return a random integer.
 */
 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 );
 }
示例#6
0
        /*
        ** 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.
        */
        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 );
              pVal.u.i = -1 * pVal.u.i;
              /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */
              pVal.r = (double)-1 * 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;
        }
示例#7
0
        /*
        ** group_concat(EXPR, ?SEPARATOR?)
        */
        static void groupConcatStep(
            sqlite3_context context,
            int argc,
            sqlite3_value[] argv
            )
        {
            string zVal;
              //StrAccum pAccum;
              string zSep;
              int nVal, nSep;
              Debug.Assert( argc == 1 || argc == 2 );
              if ( sqlite3_value_type( argv[0] ) == SQLITE_NULL )
            return;
              Mem pMem = sqlite3_aggregate_context( context, 1 );//sizeof(*pAccum));
              if ( pMem._StrAccum == null )
            pMem._StrAccum = new StrAccum( 100 );
              //pAccum = pMem._StrAccum;

              //if ( pMem._StrAccum != null )
              //{
              sqlite3 db = sqlite3_context_db_handle( context );
              //int firstTerm = pMem._StrAccum.useMalloc == 0 ? 1 : 0;
              //pMem._StrAccum.useMalloc = 2;
              pMem._StrAccum.mxAlloc = db.aLimit[SQLITE_LIMIT_LENGTH];
              if ( pMem._StrAccum.Context == null ) // first term
            pMem._StrAccum.Context = pMem;
              else
              {
            if ( argc == 2 )
            {
              zSep = sqlite3_value_text( argv[1] );
              nSep = sqlite3_value_bytes( argv[1] );
            }
            else
            {
              zSep = ",";
              nSep = 1;
            }
            sqlite3StrAccumAppend( pMem._StrAccum, zSep, nSep );
              }
              zVal = sqlite3_value_text( argv[0] );
              nVal = sqlite3_value_bytes( argv[0] );
              sqlite3StrAccumAppend( pMem._StrAccum, zVal, nVal );
              //}
        }
示例#8
0
        /*
        ** 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.
        */
        /// <summary>
        /// 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)'
        /// </summary>
        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);
            }
        }
示例#9
0
 /*
 ** Return the number of bytes in the sqlite3_value object assuming
 ** that it uses the encoding "enc"
 */
 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;
 }
示例#10
0
 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 );
     //}
       }
 }
示例#11
0
        /*
        ** An SQL user-function registered to do the work of an DETACH statement. The
        ** three arguments to the function come directly from a detach statement:
        **
        **     DETACH DATABASE x
        **
        **     SELECT sqlite_detach(x)
        */
        static void detachFunc(
            sqlite3_context context,
            int NotUsed,
            sqlite3_value[] argv
            )
        {
            string zName = zName = argv[0].z != null && ( argv[0].z.Length > 0 ) ? sqlite3_value_text( argv[0] ) : "";//(sqlite3_value_text(argv[0]);
              sqlite3 db = sqlite3_context_db_handle( context );
              int i;
              Db pDb = null;
              StringBuilder zErr = new StringBuilder( 200 );

              UNUSED_PARAMETER( NotUsed );

              if ( zName == null )
            zName = "";
              for ( i = 0; i < db.nDb; i++ )
              {
            pDb = db.aDb[i];
            if ( pDb.pBt == null )
              continue;
            if ( pDb.zName.Equals( zName, StringComparison.InvariantCultureIgnoreCase ) )
              break;
              }

              if ( i >= db.nDb )
              {
            sqlite3_snprintf( 200, zErr, "no such database: %s", zName );
            goto detach_error;
              }
              if ( i < 2 )
              {
            sqlite3_snprintf( 200, zErr, "cannot detach database %s", zName );
            goto detach_error;
              }
              if ( 0 == db.autoCommit )
              {
            sqlite3_snprintf( 200, zErr,
            "cannot DETACH database within transaction" );
            goto detach_error;
              }
              if ( sqlite3BtreeIsInReadTrans( pDb.pBt ) || sqlite3BtreeIsInBackup( pDb.pBt ) )
              {
            sqlite3_snprintf( 200, zErr, "database %s is locked", zName );
            goto detach_error;
              }

              sqlite3BtreeClose( ref pDb.pBt );
              pDb.pBt = null;
              pDb.pSchema = null;
              sqlite3ResetInternalSchema( db, 0 );
              return;

            detach_error:
              sqlite3_result_error( context, zErr.ToString(), -1 );
        }
示例#12
0
        /*
        ** Implementation of the length() function
        */
        static void lengthFunc(
            sqlite3_context context,
            int argc,
            sqlite3_value[] argv
            )
        {
            int len;

              Debug.Assert( argc == 1 );
              UNUSED_PARAMETER( argc );
              switch ( sqlite3_value_type( argv[0] ) )
              {
            case SQLITE_BLOB:
            case SQLITE_INTEGER:
            case SQLITE_FLOAT:
              {
            sqlite3_result_int( context, sqlite3_value_bytes( argv[0] ) );
            break;
              }
            case SQLITE_TEXT:
              {
            byte[] z = sqlite3_value_blob( argv[0] );
            if ( z == null )
              return;
            len = 0;
            int iz = 0;
            while ( iz < z.Length && z[iz] != '\0' )
            {
              len++;
              SQLITE_SKIP_UTF8( z, ref iz );
            }
            sqlite3_result_int( context, len );
            break;
              }
            default:
              {
            sqlite3_result_null( context );
            break;
              }
              }
        }
示例#13
0
        /*
        ** 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.
        */
        static void likeFunc(
            sqlite3_context context,
            int argc,
            sqlite3_value[] argv
            )
        {
            string zA, zB;
              int 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
            sqlite3_like_count.iValue++;
            #endif
            sqlite3_result_int( context, patternCompare( zB, zA, pInfo, escape ) ? 1 : 0 );
              }
        }
示例#14
0
 /*
 ** Implementation of the last_insert_rowid() SQL function.  The return
 ** value is the same as the sqlite3_last_insert_rowid() API function.
 */
 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 ) );
 }
示例#15
0
 /*
 ** The hex() function.  Interpret the argument as a blob.  Return
 ** a hexadecimal rendering as text.
 */
 static void hexFunc(
     sqlite3_context context,
     int argc,
     sqlite3_value[] argv
     )
 {
     int i, n;
       byte[] pBlob;
       //string zHex, z;
       Debug.Assert( argc == 1 );
       UNUSED_PARAMETER( argc );
       pBlob = sqlite3_value_blob( argv[0] );
       n = sqlite3_value_bytes( argv[0] );
       Debug.Assert( n == ( pBlob == null ? 0 : pBlob.Length ) );  /* No encoding change */
       StringBuilder zHex = new StringBuilder( n * 2 + 1 );
       //  z = zHex = contextMalloc(context, ((i64)n)*2 + 1);
       if ( zHex != null )
       {
     for ( i = 0; i < n; i++ )
     {//, pBlob++){
       byte c = pBlob[i];
       zHex.Append( hexdigits[( c >> 4 ) & 0xf] );
       zHex.Append( hexdigits[c & 0xf] );
     }
     sqlite3_result_text( context, zHex, n * 2, null ); //sqlite3_free );
       }
 }
示例#16
0
 /* 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.
 */
 /*
 ** 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];
示例#17
0
        /*
        ** The replace() function.  Three arguments are all strings: call
        ** them A, B, and C. The result is also a string which is derived
        ** from A by replacing every occurance of B with C.  The match
        ** must be exact.  Collating sequences are not used.
        */
        static void replaceFunc(
            sqlite3_context context,
            int argc,
            sqlite3_value[] argv
            )
        {
            string zStr;        /* The input string A */
              string zPattern;    /* The pattern string B */
              string zRep;        /* The replacement string C */
              string zOut;              /* The output */
              int nStr;                /* Size of zStr */
              int nPattern;            /* Size of zPattern */
              int nRep;                /* Size of zRep */
              int nOut;                /* Maximum size of zOut */
              //int loopLimit;           /* Last zStr[] that might match zPattern[] */
              int i, j;                /* Loop counters */

              Debug.Assert( argc == 3 );
              UNUSED_PARAMETER( argc );
              zStr = sqlite3_value_text( argv[0] );
              if ( zStr == null )
            return;
              nStr = sqlite3_value_bytes( argv[0] );
              Debug.Assert( zStr == sqlite3_value_text( argv[0] ) );  /* No encoding change */
              zPattern = sqlite3_value_text( argv[1] );
              if ( zPattern == null )
              {
            Debug.Assert( sqlite3_value_type( argv[1] ) == SQLITE_NULL
              //|| sqlite3_context_db_handle( context ).mallocFailed != 0
            );
            return;
              }
              if ( zPattern == "" )
              {
            Debug.Assert( sqlite3_value_type( argv[1] ) != SQLITE_NULL );
            sqlite3_result_value( context, argv[0] );
            return;
              }
              nPattern = sqlite3_value_bytes( argv[1] );
              Debug.Assert( zPattern == sqlite3_value_text( argv[1] ) );  /* No encoding change */
              zRep = sqlite3_value_text( argv[2] );
              if ( zRep == null )
            return;
              nRep = sqlite3_value_bytes( argv[2] );
              Debug.Assert( zRep == sqlite3_value_text( argv[2] ) );
              nOut = nStr + 1;
              Debug.Assert( nOut < SQLITE_MAX_LENGTH );
              //zOut = contextMalloc(context, (i64)nOut);
              //if( zOut==0 ){
              //  return;
              //}
              //loopLimit = nStr - nPattern;
              //for(i=j=0; i<=loopLimit; i++){
              //  if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
              //    zOut[j++] = zStr[i];
              //  }else{
              //    u8 *zOld;
              // sqlite3 db = sqlite3_context_db_handle( context );
              //    nOut += nRep - nPattern;
              //testcase( nOut-1==db->aLimit[SQLITE_LIMIT_LENGTH] );
              //testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] );
              //if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){
              //      sqlite3_result_error_toobig(context);
              //      sqlite3_free(zOut);
              //      return;
              //    }
              //    zOld = zOut;
              //    zOut = sqlite3_realloc(zOut, (int)nOut);
              //    if( zOut==0 ){
              //      sqlite3_result_error_nomem(context);
              //      sqlite3_free(zOld);
              //      return;
              //    }
              //    memcpy(&zOut[j], zRep, nRep);
              //    j += nRep;
              //    i += nPattern-1;
              //  }
              //}
              //Debug.Assert( j+nStr-i+1==nOut );
              //memcpy(&zOut[j], zStr[i], nStr-i);
              //j += nStr - i;
              //Debug.Assert( j<=nOut );
              //zOut[j] = 0;
              zOut = zStr.Replace( zPattern, zRep );
              j = zOut.Length;
              sqlite3_result_text( context, zOut, j, null );//sqlite3_free );
        }
示例#18
0
        /*
        ** Implementation of the non-aggregate min() and max() functions
        */
        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] );
        }
示例#19
0
        /*
        ** An SQL user-function registered to do the work of an ATTACH statement. The
        ** three arguments to the function come directly from an attach statement:
        **
        **     ATTACH DATABASE x AS y KEY z
        **
        **     SELECT sqlite_attach(x, y, z)
        **
        ** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
        ** third argument.
        */
        static void attachFunc(
            sqlite3_context context,
            int NotUsed,
            sqlite3_value[] argv
            )
        {
            int i;
              int rc = 0;
              sqlite3 db = sqlite3_context_db_handle( context );
              string zName;
              string zFile;
              Db aNew = null;
              string zErrDyn = "";

              UNUSED_PARAMETER( NotUsed );

              zFile = argv[0].z != null && ( argv[0].z.Length > 0 ) && argv[0].flags != MEM_Null ? sqlite3_value_text( argv[0] ) : "";
              zName = argv[1].z != null && ( argv[1].z.Length > 0 ) && argv[1].flags != MEM_Null ? sqlite3_value_text( argv[1] ) : "";
              //if( zFile==null ) zFile = "";
              //if ( zName == null ) zName = "";

              /* Check for the following errors:
              **
              **     * Too many attached databases,
              **     * Transaction currently open
              **     * Specified database name already being used.
              */
              if ( db.nDb >= db.aLimit[SQLITE_LIMIT_ATTACHED] + 2 )
              {
            zErrDyn = sqlite3MPrintf( db, "too many attached databases - max %d",
            db.aLimit[SQLITE_LIMIT_ATTACHED]
            );
            goto attach_error;
              }
              if ( 0 == db.autoCommit )
              {
            zErrDyn = sqlite3MPrintf( db, "cannot ATTACH database within transaction" );
            goto attach_error;
              }
              for ( i = 0; i < db.nDb; i++ )
              {
            string z = db.aDb[i].zName;
            Debug.Assert( z != null && zName != null );
            if ( z.Equals( zName, StringComparison.InvariantCultureIgnoreCase ) )
            {
              zErrDyn = sqlite3MPrintf( db, "database %s is already in use", zName );
              goto attach_error;
            }
              }

              /* Allocate the new entry in the db.aDb[] array and initialise the schema
              ** hash tables.
              */
              /* Allocate the new entry in the db.aDb[] array and initialise the schema
              ** hash tables.
              */
              //if( db.aDb==db.aDbStatic ){
              //  aNew = sqlite3DbMallocRaw(db, sizeof(db.aDb[0])*3 );
              //  if( aNew==0 ) return;
              //  memcpy(aNew, db.aDb, sizeof(db.aDb[0])*2);
              //}else {
              if ( db.aDb.Length <= db.nDb )
            Array.Resize( ref db.aDb, db.nDb + 1 );//aNew = sqlite3DbRealloc(db, db.aDb, sizeof(db.aDb[0])*(db.nDb+1) );
              if ( db.aDb == null )
            return;   // if( aNew==0 ) return;
              //}
              db.aDb[db.nDb] = new Db();//db.aDb = aNew;
              aNew = db.aDb[db.nDb];//memset(aNew, 0, sizeof(*aNew));
              //  memset(aNew, 0, sizeof(*aNew));

              /* Open the database file. If the btree is successfully opened, use
              ** it to obtain the database schema. At this point the schema may
              ** or may not be initialised.
              */
              rc = sqlite3BtreeOpen( zFile, db, ref aNew.pBt, 0,
                        db.openFlags | SQLITE_OPEN_MAIN_DB );
              db.nDb++;
              if ( rc == SQLITE_CONSTRAINT )
              {
            rc = SQLITE_ERROR;
            zErrDyn = sqlite3MPrintf( db, "database is already attached" );
              }
              else if ( rc == SQLITE_OK )
              {
            Pager pPager;
            aNew.pSchema = sqlite3SchemaGet( db, aNew.pBt );
            if ( aNew.pSchema == null )
            {
              rc = SQLITE_NOMEM;
            }
            else if ( aNew.pSchema.file_format != 0 && aNew.pSchema.enc != ENC( db ) )
            {
              zErrDyn = sqlite3MPrintf( db,
              "attached databases must use the same text encoding as main database" );
              rc = SQLITE_ERROR;
            }
            pPager = sqlite3BtreePager( aNew.pBt );
            sqlite3PagerLockingMode( pPager, db.dfltLockMode );
            sqlite3BtreeSecureDelete( aNew.pBt,
                                 sqlite3BtreeSecureDelete( db.aDb[0].pBt, -1 ) );
              }
              aNew.safety_level = 3;
              aNew.zName = zName;//sqlite3DbStrDup(db, zName);
              //if( rc==SQLITE_OK && aNew.zName==0 ){
              //  rc = SQLITE_NOMEM;
              //}

            #if SQLITE_HAS_CODEC
              if ( rc == SQLITE_OK )
              {
            //extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
            //extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
            int nKey;
            string zKey;
            int t = sqlite3_value_type( argv[2] );
            switch ( t )
            {
              case SQLITE_INTEGER:
              case SQLITE_FLOAT:
            zErrDyn = "Invalid key value"; //sqlite3DbStrDup( db, "Invalid key value" );
            rc = SQLITE_ERROR;
            break;

              case SQLITE_TEXT:
              case SQLITE_BLOB:
            nKey = sqlite3_value_bytes( argv[2] );
            zKey = sqlite3_value_blob( argv[2] ).ToString(); // (char *)sqlite3_value_blob(argv[2]);
            rc = sqlite3CodecAttach( db, db.nDb - 1, zKey, nKey );
            break;

              case SQLITE_NULL:
            /* No key specified.  Use the key from the main database */
            sqlite3CodecGetKey( db, 0, out zKey, out nKey ); //sqlite3CodecGetKey(db, 0, (void**)&zKey, nKey);
            rc = sqlite3CodecAttach( db, db.nDb - 1, zKey, nKey );
            break;
            }
              }
            #endif

              /* If the file was opened successfully, read the schema for the new database.
            ** If this fails, or if opening the file failed, then close the file and
            ** remove the entry from the db.aDb[] array. i.e. put everything back the way
            ** we found it.
            */
              if ( rc == SQLITE_OK )
              {
            sqlite3BtreeEnterAll( db );
            rc = sqlite3Init( db, ref zErrDyn );
            sqlite3BtreeLeaveAll( db );
              }
              if ( rc != 0 )
              {
            int iDb = db.nDb - 1;
            Debug.Assert( iDb >= 2 );
            if ( db.aDb[iDb].pBt != null )
            {
              sqlite3BtreeClose( ref db.aDb[iDb].pBt );
              db.aDb[iDb].pBt = null;
              db.aDb[iDb].pSchema = null;
            }
            sqlite3ResetInternalSchema( db, 0 );
            db.nDb = iDb;
            if ( rc == SQLITE_NOMEM || rc == SQLITE_IOERR_NOMEM )
            {
              ////        db.mallocFailed = 1;
              sqlite3DbFree( db, ref zErrDyn );
              zErrDyn = sqlite3MPrintf( db, "out of memory" );
            }
            else if ( zErrDyn == "" )
            {
              zErrDyn = sqlite3MPrintf( db, "unable to open database: %s", zFile );
            }
            goto attach_error;
              }

              return;

            attach_error:
              /* Return an error if we get here */
              if ( zErrDyn != "" )
              {
            sqlite3_result_error( context, zErrDyn, -1 );
            sqlite3DbFree( db, ref zErrDyn );
              }
              if ( rc != 0 )
            sqlite3_result_error_code( context, rc );
        }
示例#20
0
        /*
        ** Routines to implement min() and max() aggregate functions.
        */
        static void minmaxStep(
            sqlite3_context context,
            int NotUsed,
            sqlite3_value[] argv
            )
        {
            Mem pArg = (Mem)argv[0];
              Mem pBest;
              UNUSED_PARAMETER( NotUsed );

              if ( sqlite3_value_type( argv[0] ) == SQLITE_NULL )
            return;
              pBest = (Mem)sqlite3_aggregate_context( context, 1 );//sizeof(*pBest));
              //if ( pBest == null ) return;

              if ( pBest.flags != 0 )
              {
            bool max;
            int cmp;
            CollSeq pColl = sqlite3GetFuncCollSeq( context );
            /* This step function is used for both the min() and max() aggregates,
            ** the only difference between the two being that the sense of the
            ** comparison is inverted. For the max() aggregate, the
            ** sqlite3_context_db_handle() function returns (void *)-1. For min() it
            ** returns (void *)db, where db is the sqlite3* database pointer.
            ** Therefore the next statement sets variable 'max' to 1 for the max()
            ** aggregate, or 0 for min().
            */
            max = sqlite3_context_db_handle( context ) != null && (int)sqlite3_user_data( context ) != 0;
            cmp = sqlite3MemCompare( pBest, pArg, pColl );
            if ( ( max && cmp < 0 ) || ( !max && cmp > 0 ) )
            {
              sqlite3VdbeMemCopy( pBest, pArg );
            }
              }
              else
              {
            sqlite3VdbeMemCopy( pBest, pArg );
              }
        }
示例#21
0
        /// <summary>
        /// This function is used by SQL generated to implement the
        /// ALTER TABLE command. The first argument is the text of a CREATE TRIGGER
        /// statement. The second is a table name. The table name in the CREATE
        /// TRIGGER statement is replaced with the third argument and the result
        /// returned. This is analagous to renameTableFunc() above, except for CREATE
        /// TRIGGER, not CREATE INDEX and CREATE TABLE.
        /// </summary>
        static void renameTriggerFunc(
		sqlite3_context context,
		int NotUsed,
		sqlite3_value[] argv
		)
        {
            string zSql = sqlite3_value_text(argv[0]);
            string zTableName = sqlite3_value_text(argv[1]);

            int token = 0;
            Token tname = new Token();
            int dist = 3;
            int zCsr = 0;
            int zLoc = 0;
            int len = 1;
            string zRet;

            sqlite3 db = sqlite3_context_db_handle(context);

            UNUSED_PARAMETER(NotUsed);

            /* The principle used to locate the table name in the CREATE TRIGGER
            ** statement is that the table name is the first token that is immediatedly
            ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
            ** of TK_WHEN, TK_BEGIN or TK_FOR.
            */
            if (zSql != null)
            {
                do
                {

                    if (zCsr == zSql.Length)
                    {
                        /* Ran out of input before finding the table name. Return NULL. */
                        return;
                    }

                    /* Store the token that zCsr points to in tname. */
                    zLoc = zCsr;
                    tname.z = zSql.Substring(zCsr, len);//(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);

                    /* Variable 'dist' stores the number of tokens read since the most
                    ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN
                    ** token is read and 'dist' equals 2, the condition stated above
                    ** to be met.
                    **
                    ** Note that ON cannot be a database, table or column name, so
                    ** there is no need to worry about syntax like
                    ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
                    */
                    dist++;
                    if (token == TK_DOT || token == TK_ON)
                    {
                        dist = 0;
                    }
                } while (dist != 2 || (token != TK_WHEN && token != TK_FOR && token != TK_BEGIN));

                /* Variable tname now contains the token that is the old table-name
                ** in the CREATE TRIGGER statement.
                */
                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);
            }
        }
示例#22
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.
 */
 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] );
       }
 }
示例#23
0
        /*
        ** Count the number of times that the LIKE operator (or GLOB which is
        ** just a variation of LIKE) gets called.  This is used for testing
        ** only.
        */
        //static int sqlite3_like_count = 0;

        #endif

        #if !SQLITE_OMIT_COMPILEOPTION_DIAGS

        /*
        ** Implementation of the sqlite_compileoption_used() function.
        ** The result is an integer that identifies if the compiler option
        ** was used to build SQLite.
        */
        static void compileoptionusedFunc(
            sqlite3_context context,
            int argc,
            sqlite3_value[] argv
            )
        {
            string zOptName;
              Debug.Assert( argc == 1 );
              UNUSED_PARAMETER( argc );
              /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL
              ** function is a wrapper around the sqlite3_compileoption_used() C/C++
              ** function.
              */
              if ( ( zOptName = sqlite3_value_text( argv[0] ) ) != null )
              {
            sqlite3_result_int( context, sqlite3_compileoption_used( zOptName ) );
              }
        }
示例#24
0
        /* 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.
        */
        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 )
              {
            sqlite3VdbeChangeEncoding( pVal, enc & ~SQLITE_UTF16_ALIGNED );
            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;
              }
        }
示例#25
0
 /*
 ** Free an sqlite3_value object
 */
 static void sqlite3ValueFree( ref sqlite3_value v )
 {
     if ( v == null )
     return;
       sqlite3VdbeMemRelease( v );
       sqlite3DbFree( v.db, ref v );
 }
示例#26
0
 /*
 ** 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;
     }
     }
 }
示例#27
0
 /*
 ** Change the string value of an sqlite3_value object
 */
 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 );
 }
示例#28
0
 /*
 ** Implementation of the sqlite_compileoption_get() function.
 ** The result is a string that identifies the compiler options
 ** used to build SQLite.
 */
 static void compileoptiongetFunc(
     sqlite3_context context,
     int argc,
     sqlite3_value[] argv
     )
 {
     int n;
       Debug.Assert( argc == 1 );
       UNUSED_PARAMETER( argc );
       /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function
       ** is a wrapper around the sqlite3_compileoption_get() C/C++ function.
       */
       n = sqlite3_value_int( argv[0] );
       sqlite3_result_text( context, sqlite3_compileoption_get( n ), -1, SQLITE_STATIC );
 }
示例#29
0
        /*
        ** EXPERIMENTAL - This is not an official function.  The interface may
        ** change.  This function may disappear.  Do not write code that depends
        ** on this function.
        **
        ** Implementation of the QUOTE() function.  This function takes a single
        ** argument.  If the argument is numeric, the return value is the same as
        ** the argument.  If the argument is NULL, the return value is the string
        ** "NULL".  Otherwise, the argument is enclosed in single quotes with
        ** single-quote escapes.
        */
        static void quoteFunc(
            sqlite3_context context,
            int argc,
            sqlite3_value[] argv
            )
        {
            Debug.Assert( argc == 1 );
              UNUSED_PARAMETER( argc );

              switch ( sqlite3_value_type( argv[0] ) )
              {
            case SQLITE_INTEGER:
            case SQLITE_FLOAT:
              {
            sqlite3_result_value( context, argv[0] );
            break;
              }
            case SQLITE_BLOB:
              {
            StringBuilder zText;
            byte[] zBlob = sqlite3_value_blob( argv[0] );
            int nBlob = sqlite3_value_bytes( argv[0] );
            Debug.Assert( zBlob.Length == sqlite3_value_blob( argv[0] ).Length ); /* No encoding change */
            zText = new StringBuilder( 2 * nBlob + 4 );//(char*)contextMalloc(context, (2*(i64)nBlob)+4);
            zText.Append( "X'" );
            if ( zText != null )
            {
              int i;
              for ( i = 0; i < nBlob; i++ )
              {
                zText.Append( hexdigits[( zBlob[i] >> 4 ) & 0x0F] );
                zText.Append( hexdigits[( zBlob[i] ) & 0x0F] );
              }
              zText.Append( "'" );
              //zText[( nBlob * 2 ) + 2] = '\'';
              //zText[( nBlob * 2 ) + 3] = '\0';
              //zText[0] = 'X';
              //zText[1] = '\'';
              sqlite3_result_text( context, zText, -1, SQLITE_TRANSIENT );
              //sqlite3_free( zText );
            }
            break;
              }
            case SQLITE_TEXT:
              {
            int i, j;
            int n;
            string zArg = sqlite3_value_text( argv[0] );
            StringBuilder z;

            if ( zArg == null || zArg.Length == 0 )
              return;
            for ( i = 0, n = 0; i < zArg.Length; i++ )
            {
              if ( zArg[i] == '\'' )
                n++;
            }
            z = new StringBuilder( i + n + 3 );// contextMalloc(context, ((i64)i)+((i64)n)+3);
            if ( z != null )
            {
              z.Append( '\'' );
              for ( i = 0, j = 1; i < zArg.Length && zArg[i] != 0; i++ )
              {
                z.Append( (char)zArg[i] );
                j++;
                if ( zArg[i] == '\'' )
                {
                  z.Append( '\'' );
                  j++;
                }
              }
              z.Append( '\'' );
              j++;
              //z[j] = '\0'; ;
              sqlite3_result_text( context, z, j, null );//sqlite3_free );
            }
            break;
              }
            default:
              {
            Debug.Assert( sqlite3_value_type( argv[0] ) == SQLITE_NULL );
            sqlite3_result_text( context, "NULL", 4, SQLITE_STATIC );
            break;
              }
              }
        }
示例#30
0
 /*
 ** Implementation of the round() function
 */
 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 );
 }