Ejemplo n.º 1
0
        public static RC Savepoint(Context ctx, IPager.SAVEPOINT op, int savepoint)
        {
            Debug.Assert(op == IPager.SAVEPOINT.RELEASE || op == IPager.SAVEPOINT.ROLLBACK || op == IPager.SAVEPOINT.BEGIN);
            Debug.Assert(savepoint >= 0);
            RC rc = RC.OK;

            if (ctx.VTrans.data != null)
            {
                for (int i = 0; rc == RC.OK && i < ctx.VTrans.length; i++)
                {
                    VTable       vtable       = ctx.VTrans[i];
                    ITableModule itablemodule = vtable.Module.IModule;
                    if (vtable.IVTable != null && itablemodule.Version >= 2)
                    {
                        Func <VTable, int, int> method = null;
                        switch (op)
                        {
                        case IPager.SAVEPOINT.BEGIN:
                            method            = itablemodule.Savepoint;
                            vtable.Savepoints = savepoint + 1;
                            break;

                        case IPager.SAVEPOINT.ROLLBACK:
                            method = itablemodule.RollbackTo;
                            break;

                        default:
                            method = itablemodule.Release;
                            break;
                        }
                        if (method != null && vtable.Savepoints > savepoint)
                        {
                            rc = (RC)method(vtable.IVTable, savepoint);
                        }
                    }
                }
            }
            return(rc);
        }
Ejemplo n.º 2
0
        public static RC Begin(Context ctx, VTable vtable)
        {
            // Special case: If ctx->aVTrans is NULL and ctx->nVTrans is greater than zero, then this function is being called from within a
            // virtual module xSync() callback. It is illegal to write to virtual module tables in this case, so return SQLITE_LOCKED.
            if (InSync(ctx))
            {
                return(RC.LOCKED);
            }
            if (vtable == null)
            {
                return(RC.OK);
            }
            RC           rc      = RC.OK;
            ITableModule imodule = vtable.IVTable.IModule;

            if (imodule.Begin != null)
            {
                // If pVtab is already in the aVTrans array, return early
                for (int i = 0; i < ctx.VTrans.length; i++)
                {
                    if (ctx.VTrans[i] == vtable)
                    {
                        return(RC.OK);
                    }
                }
                // Invoke the xBegin method. If successful, add the vtab to the sqlite3.aVTrans[] array.
                rc = GrowVTrans(ctx);
                if (rc == RC.OK)
                {
                    rc = imodule.Begin(vtable.IVTable);
                    if (rc == RC.OK)
                    {
                        AddToVTrans(ctx, vtable);
                    }
                }
            }
            return(rc);
        }
Ejemplo n.º 3
0
        public static RC CreateModule(Context ctx, string name, ITableModule imodule, object aux, Action <object> destroy)
        {
            RC rc = RC.OK;

            MutexEx.Enter(ctx.Mutex);
            int nameLength = name.Length;

            if (ctx.Modules.Find(name, nameLength, (TableModule)null) != null)
            {
                rc = SysEx.MISUSE_BKPT();
            }
            else
            {
                TableModule module = new TableModule(); //: _tagalloc(ctx, sizeof(TableModule) + nameLength + 1)
                if (module != null)
                {
                    var nameCopy = name;
                    module.Name    = nameCopy;
                    module.IModule = imodule;
                    module.Aux     = aux;
                    module.Destroy = destroy;
                    TableModule del = (TableModule)ctx.Modules.Insert(nameCopy, nameLength, module);
                    Debug.Assert(del == null && del == module);
                    if (del != null)
                    {
                        ctx.MallocFailed = true;
                        C._tagfree(ctx, ref del);
                    }
                }
            }
            rc = SysEx.ApiExit(ctx, rc);
            if (rc != RC.OK && destroy != null)
            {
                destroy(aux);
            }
            MutexEx.Leave(ctx.Mutex);
            return(rc);
        }
Ejemplo n.º 4
0
        public static FuncDef OverloadFunction(Context ctx, FuncDef def, int argsLength, Expr expr)
        {
            // Check to see the left operand is a column in a virtual table
            if (C._NEVER(expr == null))
            {
                return(def);
            }
            if (expr.OP != TK.COLUMN)
            {
                return(def);
            }
            Table table = expr.Table;

            if (C._NEVER(table == null))
            {
                return(def);
            }
            if ((table.TabFlags & TF.Virtual) == 0)
            {
                return(def);
            }
            IVTable ivtable = GetVTable(ctx, table).IVTable;

            Debug.Assert(ivtable != null);
            Debug.Assert(ivtable.IModule != null);
            ITableModule imodule = (ITableModule)ivtable.IModule;

            if (imodule.FindFunction == null)
            {
                return(def);
            }

            // Call the xFindFunction method on the virtual table implementation to see if the implementation wants to overload this function
            string lowerName = def.Name;
            RC     rc        = RC.OK;
            Action <FuncContext, int, Mem[]> func = null;

            object[] args = null;
            if (lowerName != null)
            {
                lowerName = lowerName.ToLowerInvariant();
                rc        = imodule.FindFunction(ivtable, argsLength, lowerName, func, args);
                C._tagfree(ctx, ref lowerName);
            }
            if (rc == RC.OK)
            {
                return(def);
            }

            // Create a new ephemeral function definition for the overloaded function
            FuncDef newFunc = new FuncDef();//: (FuncDef*)_tagalloc(ctx, sizeof(FuncDef) + _strlen30(def->Name) + 1, true);

            if (newFunc == null)
            {
                return(def);
            }
            newFunc          = def._memcpy();
            newFunc.Name     = def.Name;
            newFunc.Func     = func;
            newFunc.UserData = args;
            newFunc.Flags   |= FUNC.EPHEM;
            return(newFunc);
        }