Beispiel #1
0
 static bool SetDateTimeToCurrent(FuncContext fctx, DateTime p)
 {
     Context ctx = Vdbe.Context_Ctx(fctx);
     if (ctx.Vfs.CurrentTimeInt64(ref p.JD) == RC.OK)
     {
         p.ValidJD = true;
         return false;
     }
     return true;
 }
Beispiel #2
0
        static void RenameTriggerFunc(FuncContext fctx, int notUsed, Mem[] argv)
        {
            Context ctx       = Vdbe.Context_Ctx(fctx);
            string  sql       = Vdbe.Value_Text(argv[0]);
            string  tableName = Vdbe.Value_Text(argv[1]);

            int   z = 0, zLoc = 0;
            int   length = 1;
            TK    token  = 0;
            Token tname  = new Token();
            int   dist   = 3;

            // 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 (sql != null)
            {
                return;
            }
            do
            {
                if (z == sql.Length)
                {
                    return; // Ran out of input before finding the table name. Return NULL.
                }
                // Store the token that zCsr points to in tname.
                zLoc         = z;
                tname.data   = sql.Substring(z, length);
                tname.length = (uint)length;

                // 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
                {
                    z     += length;
                    length = (z == sql.Length ? 1 : Parse.GetToken(sql, z, ref token));
                } while (token == TK.SPACE);
                Debug.Assert(length > 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.
            string r = C._mtagprintf(ctx, "%.*s\"%w\"%s", zLoc, sql.Substring(0, zLoc), tableName, sql.Substring(zLoc + (int)tname.length));

            Vdbe.Result_Text(fctx, r, -1, C.DESTRUCTOR_DYNAMIC);
        }
Beispiel #3
0
        static void RenameParentFunc(FuncContext fctx, int notUsed, Mem[] argv)
        {
            Context ctx     = Vdbe.Context_Ctx(fctx);
            string  input   = Vdbe.Value_Text(argv[0]);
            string  oldName = Vdbe.Value_Text(argv[1]);
            string  newName = Vdbe.Value_Text(argv[2]);

            int zIdx;        // Pointer to token
            int zLeft = 0;   // Pointer to remainder of String

            TK token = 0;    // Type of token

            string output = string.Empty;
            int    n; // Length of token z

            for (int z = 0; z < input.Length; z += n)
            {
                n = Parse.GetToken(input, z, ref token);
                if (token == TK.REFERENCES)
                {
                    string parent;
                    do
                    {
                        z += n;
                        n  = Parse.GetToken(input, z, ref token);
                    } while (token == TK.SPACE);

                    parent = (z + n < input.Length ? input.Substring(z, n) : string.Empty);
                    if (string.IsNullOrEmpty(parent))
                    {
                        break;
                    }
                    Parse.Dequote(ref parent);
                    if (oldName.Equals(parent, StringComparison.OrdinalIgnoreCase))
                    {
                        string out_ = C._mtagprintf(ctx, "%s%.*s\"%w\"", output, z - zLeft, input.Substring(zLeft), newName);
                        C._tagfree(ctx, ref output);
                        output = out_;
                        z     += n;
                        zLeft  = z;
                    }
                    C._tagfree(ctx, ref parent);
                }
            }

            string r = C._mtagprintf(ctx, "%s%s", output, input.Substring(zLeft));

            Vdbe.Result_Text(fctx, r, -1, DESTRUCTOR.DYNAMIC);
            C._tagfree(ctx, ref output);
        }
Beispiel #4
0
        static void RenameTableFunc(FuncContext fctx, int notUsed, Mem[] argv)
        {
            Context ctx       = Vdbe.Context_Ctx(fctx);
            string  sql       = Vdbe.Value_Text(argv[0]);
            string  tableName = Vdbe.Value_Text(argv[1]);

            if (string.IsNullOrEmpty(sql))
            {
                return;
            }
            int   length = 0;
            TK    token  = 0;
            Token tname  = new Token();

            int z = 0, zLoc = 0;

            // 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.
            do
            {
                if (z == sql.Length)
                {
                    return; // Ran out of input before finding an opening bracket. Return NULL.
                }
                // Store the token that zCsr points to in tname.
                zLoc         = z;
                tname.data   = sql.Substring(z);
                tname.length = (uint)length;

                // 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
                {
                    z     += length;
                    length = (z == sql.Length ? 1 : Parse.GetToken(sql, z, ref token));
                } while (token == TK.SPACE);
                Debug.Assert(length > 0);
            } while (token != TK.LP && token != TK.USING);

            string r = C._mtagprintf(ctx, "%.*s\"%w\"%s", zLoc, sql.Substring(0, zLoc), tableName, sql.Substring(zLoc + (int)tname.length));

            Vdbe.Result_Text(fctx, r, -1, DESTRUCTOR_DYNAMIC);
        }
Beispiel #5
0
 static void StrftimeFunc(FuncContext fctx, int argc, Mem[] argv)
 {
     {
         DateTime x = new DateTime();
         ulong n;
         int i, j;
         StringBuilder z;
         string fmt = Vdbe.Value_Text(argv[0]);
         StringBuilder zdtBuf = new StringBuilder(100);
         Mem[] argv1 = new Mem[argc - 1];
         for (i = 0; i < argc - 1; i++)
             argv[i + 1]._memcpy(ref argv1[i]);
         if (fmt == null || IsDate(fctx, argc - 1, argv1, out x)) return;
         Context ctx = Vdbe.Context_Ctx(fctx);
         for (i = 0, n = 1; i < fmt.Length; i++, n++)
         {
             if (fmt[i] == '%')
             {
                 switch ((char)fmt[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++;
             }
         }
         C.ASSERTCOVERAGE(n == (ulong)(zdtBuf.Length - 1));
         C.ASSERTCOVERAGE(n == (ulong)zdtBuf.Length);
         C.ASSERTCOVERAGE(n == (ulong)ctx.Limits[(int)LIMIT.LENGTH] + 1);
         C.ASSERTCOVERAGE(n == (ulong)ctx.Limits[(int)LIMIT.LENGTH]);
         if (n < (ulong)zdtBuf.Capacity)
             z = zdtBuf;
         else if (n > (ulong)ctx.Limits[(int)LIMIT.LENGTH])
         {
             Vdbe.Result_ErrorOverflow(fctx);
             return;
         }
         else
         {
             z = new StringBuilder((int)n);
             if (z == null)
             {
               Vdbe.Result_ErrorNoMem(fctx);
               return;
             }
         }
         ComputeJD(x);
         ComputeYMD_HMS(x);
         for (i = j = 0; i < fmt.Length; i++)
         {
             if (fmt[i] != '%')
                 z.Append((char)fmt[i]);
             else
             {
                 i++;
                 _zdtTemp.Length = 0;
                 switch ((char)fmt[i])
                 {
                     case 'd': C.__snprintf(_zdtTemp, 3, "%02d", x.D); z.Append(_zdtTemp); j += 2; break;
                     case 'f':
                         {
                             double s = x.s;
                             if (s > 59.999) s = 59.999;
                             C.__snprintf(_zdtTemp, 7, "%06.3f", s);
                             z.Append(_zdtTemp);
                             j = z.Length;
                             break;
                         }
                     case 'H': C.__snprintf(_zdtTemp, 3, "%02d", x.h); z.Append(_zdtTemp); j += 2; break;
                     case 'W': // Fall thru
                     case 'j':
                         {
                             DateTime y = new DateTime();
                             x.memcopy(y);
                             y.ValidJD = false;
                             y.M = 1;
                             y.D = 1;
                             ComputeJD(y);
                             int days = (int)((x.JD - y.JD + 43200000) / 86400000); ; // Number of days since 1st day of year
                             if (fmt[i] == 'W')
                             {
                                 int wd = (int)(((x.JD + 43200000) / 86400000) % 7);  // 0=Monday, 1=Tuesday, ... 6=Sunday
                                 C.__snprintf(_zdtTemp, 3, "%02d", (days + 7 - wd) / 7);
                                 z.Append(_zdtTemp);
                                 j += 2;
                             }
                             else
                             {
                                 C.__snprintf(_zdtTemp, 4, "%03d", days + 1);
                                 z.Append(_zdtTemp);
                                 j += 3;
                             }
                             break;
                         }
                     case 'J':
                         {
                             C.__snprintf(_zdtTemp, 20, "%.16g", x.JD / 86400000.0);
                             z.Append(_zdtTemp);
                             j = z.Length;
                             break;
                         }
                     case 'm': C.__snprintf(_zdtTemp, 3, "%02d", x.M); z.Append(_zdtTemp); j += 2; break;
                     case 'M': C.__snprintf(_zdtTemp, 3, "%02d", x.m); z.Append(_zdtTemp); j += 2; break;
                     case 's':
                         {
                             C.__snprintf(_zdtTemp, 30, "%lld", (long)(x.JD / 1000 - 210866760000L));
                             z.Append(_zdtTemp);
                             j = z.Length;
                             break;
                         }
                     case 'S': C.__snprintf(_zdtTemp, 3, "%02d", (int)x.s); z.Append(_zdtTemp); j += 2; break;
                     case 'w':
                         {
                             z.Append((((x.JD + 129600000) / 86400000) % 7));
                             break;
                         }
                     case 'Y':
                         {
                             C.__snprintf(_zdtTemp, 5, "%04d", x.Y);
                             z.Append(_zdtTemp);
                             j = z.Length;
                             break;
                         }
                     default: z.Append('%'); break;
                 }
             }
         }
         Vdbe.Result_Text(fctx, z, -1, z == (zdtBuf ? DESTRUCTOR_TRANSIENT : DESTRUCTOR_DYNAMIC);
     }
 }