Exemple #1
0
 public static void Disconnect(Context ctx, Table table)
 {
     Debug.Assert(E.IsVirtual(table));
     Debug.Assert(Btree.HoldsAllMutexes(ctx));
     Debug.Assert(MutexEx.Held(ctx.Mutex));
     for (VTable pvtable = table.VTables; pvtable != null; pvtable = pvtable.Next)
     {
         if (pvtable.Ctx == ctx)
         {
             VTable vtable = pvtable;
             vtable = vtable.Next;
             vtable.Unlock();
             break;
         }
     }
 }
Exemple #2
0
        public static void UnlockList(Context ctx)
        {
            Debug.Assert(Btree.HoldsAllMutexes(ctx));
            Debug.Assert(MutexEx.Held(ctx.Mutex));
            VTable vtable = ctx.Disconnect;

            ctx.Disconnect = null;
            if (vtable != null)
            {
                Vdbe.ExpirePreparedStatements(ctx);
                do
                {
                    VTable next = vtable.Next;
                    vtable.Unlock();
                    vtable = next;
                } while (vtable != null);
            }
        }
Exemple #3
0
        public static RC CallDestroy(Context ctx, int db, string tableName)
        {
            RC    rc    = RC.OK;
            Table table = Parse.FindTable(ctx, tableName, ctx.DBs[db].Name);

            if (C._ALWAYS(table != null && table.VTables != null))
            {
                VTable vtable = VTableDisconnectAll(ctx, table);
                Debug.Assert(rc == RC.OK);
                rc = vtable.Module.IModule.Destroy(vtable.IVTable);

                // Remove the sqlite3_vtab* from the aVTrans[] array, if applicable
                if (rc == RC.OK)
                {
                    Debug.Assert(table.VTables == vtable && vtable.Next == null);
                    vtable.IVTable = null;
                    table.VTables  = null;
                    vtable.Unlock();
                }
            }
            return(rc);
        }
Exemple #4
0
 static void CallFinaliser(Context ctx, int offset)
 {
     if (ctx.VTrans.data != null)
     {
         for (int i = 0; i < ctx.VTrans.length; i++)
         {
             VTable  vtable  = ctx.VTrans[i];
             IVTable ivtable = vtable.IVTable;
             if (ivtable != null)
             {
                 Func <IVTable, int> x = null;
                 if (offset == 0)
                 {
                     x = ivtable.IModule.Rollback;
                 }
                 else if (offset == 1)
                 {
                     x = ivtable.IModule.Commit;
                 }
                 else
                 {
                     throw new InvalidOperationException();
                 }
                 if (x != null)
                 {
                     x(ivtable);
                 }
             }
             vtable.Savepoints = 0;
             vtable.Unlock();
         }
         C._tagfree(ctx, ref ctx.VTrans.data);
         ctx.VTrans.length = 0;
         ctx.VTrans.data   = null;
     }
 }
Exemple #5
0
        static RC VTableCallConstructor(Context ctx, Table table, TableModule module, Construct_t construct, ref string errorOut)
        {
            string moduleName = table.Name;

            if (moduleName == null)
            {
                return(RC.NOMEM);
            }

            VTable vtable = new VTable();

            if (vtable == null)
            {
                C._tagfree(ctx, ref moduleName);
                return(RC.NOMEM);
            }
            vtable.Ctx    = ctx;
            vtable.Module = module;

            int db = sqlite3SchemaToIndex(ctx, table.Schema);

            table.ModuleArgs[1] = ctx.DBs[db].Name;

            // Invoke the virtual table constructor
            Debug.Assert(ctx.VTableCtx != null);
            Debug.Assert(construct != null);
            VTableContext sVtableCtx = new VTableContext();

            sVtableCtx.Table  = table;
            sVtableCtx.VTable = vtable;
            VTableContext priorCtx = ctx.VTableCtx;

            ctx.VTableCtx = sVtableCtx;

            string[] args       = table.ModuleArgs.data;
            int      argsLength = table.ModuleArgs.length;
            string   error      = null;
            RC       rc         = construct(ctx, module.Aux, argsLength, args, out vtable.IVTable, out error);

            ctx.VTableCtx = null;
            if (rc == RC.NOMEM)
            {
                ctx.MallocFailed = true;
            }

            if (rc != RC.OK)
            {
                if (error == null)
                {
                    errorOut = C._mtagprintf(ctx, "vtable constructor failed: %s", moduleName);
                }
                else
                {
                    errorOut = error;
                    error    = null; //: _free(error);
                }
                C._tagfree(ctx, ref vtable);
            }
            else if (C._ALWAYS(vtable.IVTable != null))
            {
                // Justification of ALWAYS():  A correct vtab constructor must allocate the sqlite3_vtab object if successful.
                vtable.IVTable.IModule = module.IModule;
                vtable.Refs            = 1;
                if (sVtableCtx.Table != null)
                {
                    errorOut = C._mtagprintf(ctx, "vtable constructor did not declare schema: %s", table.Name);
                    vtable.Unlock();
                    rc = RC.ERROR;
                }
                else
                {
                    // If everything went according to plan, link the new VTable structure into the linked list headed by pTab->pVTable. Then loop through the
                    // columns of the table to see if any of them contain the token "hidden". If so, set the Column COLFLAG_HIDDEN flag and remove the token from
                    // the type string.
                    vtable.Next   = table.VTables;
                    table.VTables = vtable;
                    for (int col = 0; col < table.Cols.length; col++)
                    {
                        string type = table.Cols[col].Type;
                        if (type == null)
                        {
                            continue;
                        }
                        int typeLength = type.Length;
                        int i          = 0;
                        if (string.Compare("hidden", 0, type, 0, 6, StringComparison.OrdinalIgnoreCase) == 0 || (type.Length > 6 && type[6] != ' '))
                        {
                            for (i = 0; i < typeLength; i++)
                            {
                                if (string.Compare(" hidden", 0, type, i, 7, StringComparison.OrdinalIgnoreCase) == 0 && (i + 7 == type.Length || (type[i + 7] == '\0' || type[i + 7] == ' ')))
                                {
                                    i++;
                                    break;
                                }
                            }
                        }
                        if (i < typeLength)
                        {
                            StringBuilder type2 = new StringBuilder(type);
                            int           del   = 6 + (type2.Length > i + 6 ? 1 : 0);
                            int           j;
                            for (j = i; (j + del) < typeLength; j++)
                            {
                                type2[j] = type2[j + del];
                            }
                            if (type2[i] == '\0' && i > 0)
                            {
                                Debug.Assert(type[i - 1] == ' ');
                                type2.Length = i; //: type[i - 1] = '\0';
                            }
                            table.Cols[col].ColFlags |= COLFLAG.HIDDEN;
                            table.Cols[col].Type      = type.ToString().Substring(0, j);
                        }
                    }
                }
            }

            C._tagfree(ctx, ref moduleName);
            return(rc);
        }