Ejemplo n.º 1
0
        public static bool InitCallback(object init, int argc, string[] argv, object notUsed1)
        {
            InitData data = (InitData)init;
            Context  ctx  = data.Ctx;
            int      db   = data.Db;

            Debug.Assert(argc == 3);
            Debug.Assert(MutexEx.Held(ctx.Mutex));
            E.DbClearProperty(ctx, db, SCHEMA.Empty);
            if (ctx.MallocFailed)
            {
                CorruptSchema(data, argv[0], null);
                return(true);
            }

            Debug.Assert(db >= 0 && db < ctx.DBs.length);
            if (argv == null)
            {
                return(false);              // Might happen if EMPTY_RESULT_CALLBACKS are on */
            }
            if (argv[1] == null)
            {
                CorruptSchema(data, argv[0], null);
            }
            else if (!string.IsNullOrEmpty(argv[2]))
            {
                // Call the parser to process a CREATE TABLE, INDEX or VIEW. But because ctx->init.busy is set to 1, no VDBE code is generated
                // or executed.  All the parser does is build the internal data structures that describe the table, index, or view.
                Debug.Assert(ctx.Init.Busy);
                ctx.Init.DB            = (byte)db;
                ctx.Init.NewTid        = ConvertEx.Atoi(argv[1]);
                ctx.Init.OrphanTrigger = false;
                Vdbe stmt = null;
#if DEBUG
                int rcp = Prepare(ctx, argv[2], -1, ref stmt, null);
#else
                Prepare(ctx, argv[2], -1, ref stmt, null);
#endif
                RC rc = ctx.ErrCode;
#if DEBUG
                Debug.Assert(((int)rc & 0xFF) == (rcp & 0xFF));
#endif
                ctx.Init.DB = 0;
                if (rc != RC.OK)
                {
                    if (ctx.Init.OrphanTrigger)
                    {
                        Debug.Assert(db == 1);
                    }
                    else
                    {
                        data.RC = rc;
                        if (rc == RC.NOMEM)
                        {
                            ctx.MallocFailed = true;
                        }
                        else if (rc != RC.INTERRUPT && (RC)((int)rc & 0xFF) != RC.LOCKED)
                        {
                            CorruptSchema(data, argv[0], sqlite3_errmsg(ctx));
                        }
                    }
                }
                stmt.Finalize();
            }
            else if (argv[0] == null)
            {
                CorruptSchema(data, null, null);
            }
            else
            {
                // If the SQL column is blank it means this is an index that was created to be the PRIMARY KEY or to fulfill a UNIQUE
                // constraint for a CREATE TABLE.  The index should have already been created when we processed the CREATE TABLE.  All we have
                // to do here is record the root page number for that index.
                Index index = Parse.FindIndex(ctx, argv[0], ctx.DBs[db].Name);
                if (index == null)
                {
                    // This can occur if there exists an index on a TEMP table which has the same name as another index on a permanent index.  Since
                    // the permanent table is hidden by the TEMP table, we can also safely ignore the index on the permanent table.
                    // Do Nothing
                }
                else if (!ConvertEx.Atoi(argv[1], ref index.Id))
                {
                    CorruptSchema(data, argv[0], "invalid rootpage");
                }
            }
            return(false);
        }