Ejemplo n.º 1
0
    //
    // The ISchema interface
    //

    public VxSchemaErrors Put(VxSchema schema, VxSchemaChecksums sums, 
        VxPutOpts opts)
    {
        log.print("Put\n");
        bool no_retry = (opts & VxPutOpts.NoRetry) != 0;
        int old_err_count = -1;
        IEnumerable<string> keys = schema.Keys;
        VxSchemaErrors errs = new VxSchemaErrors();

        // Sometimes we'll get schema elements in the wrong order, so retry
        // until the number of errors stops decreasing.
        while (errs.Count != old_err_count)
        {
            log.print("Calling Put on {0} entries\n", 
                old_err_count == -1 ? schema.Count : errs.Count);
            old_err_count = errs.Count;
            errs.Clear();

            List<string> tables = new List<string>();
            List<string> nontables = new List<string>();
            foreach (string key in keys)
            {
                if (schema[key].type == "Table")
                    tables.Add(key);
                else
                    nontables.Add(key);
            }

            errs.Add(PutSchemaTables(tables, schema, sums, opts));
            foreach (string key in nontables)
            {
                log.print("Calling PutSchema on {0}\n", key);
                VxSchemaError e = PutSchemaElement(schema[key], opts);
                if (e != null)
                    errs.Add(key, e);
            }
            // If we only had one schema element, retrying it isn't going to
            // fix anything.  We retry to fix ordering problems.
            if (no_retry || errs.Count == 0 || schema.Count == 1)
                break;

            log.print("Got {0} errors, old_errs={1}, retrying\n", 
                errs.Count, old_err_count);

            keys = errs.Keys.ToList();
        }
        return errs;
    }
Ejemplo n.º 2
0
    // 
    // The ISchema interface
    //

    // Note: this implementation ignores the sums.
    public VxSchemaErrors Put(VxSchema schema, VxSchemaChecksums sums, 
        VxPutOpts opts)
    {
        WvDbusMsg call = methodcall("PutSchema", 
            String.Format("{0}i", VxSchema.GetDbusSignature()));

        WvDbusWriter writer = new WvDbusWriter();

        schema.WriteSchema(writer);
        writer.Write((int)opts);
        call.Body = writer.ToArray();

        WvDbusMsg reply = bus.send_and_wait(call);
	if (reply.signature == VxSchemaErrors.GetDbusSignature())
	    return new VxSchemaErrors(reply.iter().pop());
	else
	    reply.check(VxSchemaErrors.GetDbusSignature());
	return null;
    }
Ejemplo n.º 3
0
    //
    // The ISchemaBackend interface
    //

    // Export the current schema to the backing directory, in a format that can
    // be read back later.  
    public VxSchemaErrors Put(VxSchema schema, VxSchemaChecksums sums, 
        VxPutOpts opts)
    {
        bool isbackup = (opts & VxPutOpts.IsBackup) != 0;

        DirectoryInfo dir = new DirectoryInfo(exportdir);
        dir.Create();

        foreach (var p in schema)
        {
            if (!sums.ContainsKey(p.Key))
                throw new ArgumentException("Missing checksum for " + p.Key);

            VxSchemaElement elem = p.Value;
            if (elem.text == null || elem.text == "")
                DropSchema(new string[] {elem.key});
            else
                ExportToDisk(p.Value, sums[p.Key], isbackup);
        }

        // Writing schemas to disk doesn't give us any per-element errors.
        return new VxSchemaErrors();
    }
Ejemplo n.º 4
0
    private VxSchemaErrors PutSchemaTables(List<string> tables, 
        VxSchema newschema, VxSchemaChecksums newsums, VxPutOpts opts)
    {
        VxSchema curschema = Get(tables);
        VxSchemaErrors errs = new VxSchemaErrors();

        foreach (string key in tables)
        {
            log.print("Putting table {0}\n", key);
            string curtype = curschema.ContainsKey(key) ? 
                curschema[key].type : "Table";
            string newtype = newschema.ContainsKey(key) ? 
                newschema[key].type : "Table";

            if (newtype != "Table" || curtype != "Table")
                throw new ArgumentException("PutSchemaTables called on " + 
                    "non-table element '" + key + "'.");

            // Check for the easy cases, an all-new table or table deletion
            if (!curschema.ContainsKey(key))
            {
                // New table, let PutSchemaElement handle it like before.
                VxSchemaError e = PutSchemaElement(newschema[key], opts);
                if (e != null)
                    errs.Add(key, e);
                continue;
            }
            if (!newschema.ContainsKey(key))
            {
                // Deleted table, let DropSchemaElement deal with it.
                VxSchemaError e = DropSchemaElement(key);
                if (e != null)
                    errs.Add(key, e);
                continue;
            }

            // An existing table has been modified.

            VxSchemaTable newtable;
            VxSchemaTable curtable;
            if (newschema[key] is VxSchemaTable)
                newtable = (VxSchemaTable)newschema[key];
            else
                newtable = new VxSchemaTable(newschema[key]);

            if (curschema[key] is VxSchemaTable)
                curtable = (VxSchemaTable)curschema[key];
            else
                curtable = new VxSchemaTable(curschema[key]);

            VxSchemaErrors put_table_errs = null;
            put_table_errs = PutSchemaTable(curtable, newtable, opts);

            // If anything goes wrong updating a table in destructive mode, 
            // drop and re-add it.  We want to be sure the schema is updated
            // exactly.
            bool destructive = (opts & VxPutOpts.Destructive) != 0;
            if (destructive && put_table_errs.Count > 0)
            {
                put_table_errs = null;

                log.print("Couldn't cleanly modify table '{0}'.  Dropping " + 
                    "and re-adding it.\n", newtable.name);
                VxSchemaError e = PutSchemaElement(newschema[key], opts);

                if (e != null)
                    errs.Add(key, e);
            }

            if (put_table_errs != null && put_table_errs.Count > 0)
                errs.Add(put_table_errs);
        }

        return errs;
    }
Ejemplo n.º 5
0
    public VxSchemaChecksums GetChecksums()
    {
        log.print("GetChecksums\n");
        VxSchemaChecksums sums = new VxSchemaChecksums();

        foreach (string type in ProcedureTypes)
        {
            try
            {
                if (type == "Procedure")
                {
                    // Set up self test
                    DbiExec("create procedure schemamatic_checksum_test " + 
                        "as print 'hello' ");
                }

                GetProcChecksums(sums, type, 0);

                if (type == "Procedure")
                {
                    // Self-test the checksum feature.  If mssql's checksum
                    // algorithm changes, we don't want to pretend our checksum
                    // list makes any sense!
                    string test_csum = "Procedure/schemamatic_checksum_test";
                    ulong got_csum = 0;
                    if (sums.ContainsKey(test_csum))
                        got_csum = sums[test_csum].checksums.First();
                    ulong want_csum = 0x173d6ee8;
                    if (want_csum != got_csum)
                    {
                        throw new Exception(String.Format(
                            "checksum_test_mismatch! {0} != {1}", 
                            got_csum, want_csum));
                    }
                    sums.Remove(test_csum);
                }
            }
            finally
            {
                if (type == "Procedure")
                {
                    DbiExec("drop procedure schemamatic_checksum_test");
                }
            }

            GetProcChecksums(sums, type, 1);
        }

        // Do tables separately
        GetTableChecksums(sums);

        // Do indexes separately
        AddIndexChecksumsToTables(sums);

        // Do XML schema collections separately (FIXME: only if SQL2005)
        GetXmlSchemaChecksums(sums);

        return sums;
    }
Ejemplo n.º 6
0
    void GetXmlSchemaChecksums(VxSchemaChecksums sums)
    {
        string query = @"
            select sch.name owner,
               xsc.name sch,
               cast(XML_Schema_Namespace(sch.name,xsc.name) 
                    as nvarchar(max)) contents
              into #checksum_calc
              from sys.xml_schema_collections xsc 
              join sys.schemas sch on xsc.schema_id = sch.schema_id
              where sch.name <> 'sys'
              order by sch.name, xsc.name

            select sch, convert(varbinary(8), checksum(contents))
                from #checksum_calc
            drop table #checksum_calc";

        foreach (WvSqlRow row in DbiSelect(query))
        {
            string schemaname = row[0];
            ulong checksum = 0;
            foreach (byte b in (byte[])row[1])
            {
                checksum <<= 8;
                checksum |= b;
            }

            string key = String.Format("XMLSchema/{0}", schemaname);

            log.print("schemaname={0}, checksum={1}, key={2}\n", 
                schemaname, checksum, key);
            sums.AddSum(key, checksum);
        }
    }
Ejemplo n.º 7
0
    public void TestApplySchemaDiff(ISchemaBackend backend)
    {
        log.print("In TestApplySchemaDiff({0})\n", backend.GetType().ToString());
        SchemaCreator sc = new SchemaCreator(this);
        sc.Create();

        string msg2 = "Hello, world, this used to be Func1!";
        string func1q2 = "create procedure Func1 as select '" + msg2 + "'\n";
        
        VxSchema origschema = dbus.Get();
        VxSchemaChecksums origsums = dbus.GetChecksums();
        VxSchema newschema = new VxSchema(origschema);
        VxSchemaChecksums newsums = new VxSchemaChecksums(origsums);

        // Don't bother putting the data again if we're talking to dbus: 
        // we already snuck it in the back door.
        if (backend != dbus)
            backend.Put(origschema, origsums, VxPutOpts.None);

        VxSchemaChecksums diffsums = new VxSchemaChecksums(newsums);

        // Make some changes to create an interesting diff.
        // Change the text and sums of Func1, schedule TestSchema for
        // deletion, and act like Tab2 is new.
        newschema["Procedure/Func1"].text = func1q2;
        newsums.AddSum("Procedure/Func1", 123);
        newsums.Remove("XMLSchema/TestSchema");
        origsums.Remove("Table/Tab2");
        WVASSERT(VxExec("drop table Tab2"));

        VxSchemaDiff diff = new VxSchemaDiff(origsums, newsums);
        using (IEnumerator<KeyValuePair<string,VxDiffType>> iter = 
            diff.GetEnumerator())
        {
            WVPASS(iter.MoveNext());
            WVPASSEQ(iter.Current.Key, "XMLSchema/TestSchema");
            WVPASSEQ((char)iter.Current.Value, (char)VxDiffType.Remove);
            WVPASS(iter.MoveNext());
            WVPASSEQ(iter.Current.Key, "Table/Tab2");
            WVPASSEQ((char)iter.Current.Value, (char)VxDiffType.Add);
            WVPASS(iter.MoveNext());
            WVPASSEQ(iter.Current.Key, "Procedure/Func1");
            WVPASSEQ((char)iter.Current.Value, (char)VxDiffType.Change);
            WVFAIL(iter.MoveNext());
        }

        VxSchema diffschema = newschema.GetDiffElements(diff);
        WVPASSEQ(diffschema["XMLSchema/TestSchema"].type, "XMLSchema");
        WVPASSEQ(diffschema["XMLSchema/TestSchema"].name, "TestSchema");
        WVPASSEQ(diffschema["XMLSchema/TestSchema"].text, "");
        WVPASSEQ(diffschema["Table/Tab2"].type, "Table");
        WVPASSEQ(diffschema["Table/Tab2"].name, "Tab2");
        WVPASSEQ(diffschema["Table/Tab2"].text, sc.tab2sch);
        WVPASSEQ(diffschema["Procedure/Func1"].type, "Procedure");
        WVPASSEQ(diffschema["Procedure/Func1"].name, "Func1");
        WVPASSEQ(diffschema["Procedure/Func1"].text, func1q2);

        VxSchemaErrors errs = backend.Put(diffschema, diffsums, VxPutOpts.None);
        WVPASSEQ(errs.Count, 0);

        VxSchema updated = backend.Get(null);
        WVASSERT(!updated.ContainsKey("XMLSchema/TestSchema"));
        WVPASSEQ(updated["Table/Tab1"].text, newschema["Table/Tab1"].text);
        WVPASSEQ(updated["Table/Tab2"].text, newschema["Table/Tab2"].text);
        WVPASSEQ(updated["Procedure/Func1"].text, 
            newschema["Procedure/Func1"].text);

        sc.Cleanup();
    }
Ejemplo n.º 8
0
 public VxSchemaChecksums GetChecksums()
 {
     VxSchemaChecksums sums = new VxSchemaChecksums();
     ReadExportedDir(null, sums);
     return sums;
 }
Ejemplo n.º 9
0
    // Adds the contents of extradir to the provided schema and sums.
    // Throws an ArgumentException if the directory contains an entry that
    // already exists in schema or sums.
    public static void AddFromDir(string extradir, VxSchema schema, 
        VxSchemaChecksums sums)
    {
        VxDiskSchema disk = new VxDiskSchema(extradir);

        disk.ReadExportedDir(schema, sums);
    }
Ejemplo n.º 10
0
    public void TestSubmoduleExceptions()
    {
        VxSchema schema1 = new VxSchema();
        VxSchemaChecksums sums1 = new VxSchemaChecksums();

        VxSchema schema2 = new VxSchema();
        VxSchemaChecksums sums2 = new VxSchemaChecksums();

        schema1.Add("Procedure", "Func1", "Random contents", false);
        sums1.AddSum("Procedure/Func1", 1);
        schema2.Add("Procedure", "Func1", "Random contents 2", false);
        sums2.AddSum("Procedure/Func1", 2);

        string tmpdir = GetTempDir();
        try
        {
            Directory.CreateDirectory(tmpdir);
            VxDiskSchema disk = new VxDiskSchema(tmpdir);

            disk.Put(schema2, sums2, VxPutOpts.None);

            try {
                WVEXCEPT(VxDiskSchema.AddFromDir(tmpdir, schema1, sums1))
            } catch (System.ArgumentException e) {
                WVPASSEQ(e.Message, "Conflicting schema key: Procedure/Func1");
            }
        }
        finally
        {
            Directory.Delete(tmpdir, true);
        }
	WVPASS(!Directory.Exists(tmpdir));
    }
Ejemplo n.º 11
0
    public void TestSubmoduleSupport()
    {
        VxSchema schema1 = new VxSchema();
        VxSchemaChecksums sums1 = new VxSchemaChecksums();

        VxSchema schema2 = new VxSchema();
        VxSchemaChecksums sums2 = new VxSchemaChecksums();

        schema1.Add("Table", "Tab1", "column: name=random\n", false);
        sums1.AddSum("Table/Tab1", 1);
        schema2.Add("Table", "Tab2", "column: name=ignored\n", false);
        sums2.AddSum("Table/Tab2", 2);

        string tmpdir = GetTempDir();
        try
        {
            Directory.CreateDirectory(tmpdir);
            VxDiskSchema disk = new VxDiskSchema(tmpdir);

            disk.Put(schema2, sums2, VxPutOpts.None);

            VxDiskSchema.AddFromDir(tmpdir, schema1, sums1);

            WVPASSEQ(sums1["Table/Tab1"].GetSumString(), "0x00000001");
            WVPASSEQ(schema1["Table/Tab1"].name, "Tab1");
            WVPASSEQ(schema1["Table/Tab1"].type, "Table");
            WVPASSEQ(schema1["Table/Tab1"].text, "column: name=random\n");
            WVPASSEQ(schema1["Table/Tab1"].encrypted, false);

            WVPASSEQ(sums1["Table/Tab2"].GetSumString(), "0x00000002");
            WVPASSEQ(schema1["Table/Tab2"].name, "Tab2");
            WVPASSEQ(schema1["Table/Tab2"].type, "Table");
            WVPASSEQ(schema1["Table/Tab2"].text, "column: name=ignored\n");
            WVPASSEQ(schema1["Table/Tab2"].encrypted, false);
        }
        finally
        {
            Directory.Delete(tmpdir, true);
        }
	WVPASS(!Directory.Exists(tmpdir));
    }
Ejemplo n.º 12
0
    public void TestExportSchema()
    {
        SchemaCreator sc = new SchemaCreator(this);

        string tmpdir = GetTempDir();

        DirectoryInfo tmpdirinfo = new DirectoryInfo(tmpdir);
        try
        {
            tmpdirinfo.Create();

            // Establish a baseline for the number of existing elements.
            VxSchema schema = dbus.Get();
            VxSchemaChecksums sums = dbus.GetChecksums();

            VxDiskSchema disk = new VxDiskSchema(tmpdir);
            disk.Put(schema, sums, VxPutOpts.None);

            var base_filecounts = GetFileCounts(tmpdir);

            // Clobber the directory and start fresh.
            tmpdirinfo.Delete(true);
            tmpdirinfo.Create();

            // Now create our test schema and do the real tests.
            sc.Create();

            // Check that having mangled checksums fails
            schema = dbus.Get();
            sums = new VxSchemaChecksums();

            disk = new VxDiskSchema(tmpdir);
            try {
                WVEXCEPT(disk.Put(schema, sums, VxPutOpts.None));
            } catch (Wv.Test.WvAssertionFailure e) {
                throw e;
            } catch (System.Exception e) {
                WVPASS(e is ArgumentException);
                WVPASS(e.Message.StartsWith("Missing checksum for "));
                log.print(e.ToString() + "\n");
            }

            // Check that the normal exporting works.
            schema = dbus.Get();
            sums = dbus.GetChecksums();

            WVPASSEQ(schema.Count, sums.Count);
            disk.Put(schema, sums, VxPutOpts.None);

            int backup_generation = 0;
            VerifyExportedSchema(tmpdir, schema, sums, sc, backup_generation,
                base_filecounts);

            // Check that we read back the same stuff
            VxSchema schemafromdisk = disk.Get(null);
            VxSchemaChecksums sumsfromdisk = disk.GetChecksums();

            WVPASS(1);

            TestSchemaEquality(schema, schemafromdisk);
            TestChecksumEquality(sums, sumsfromdisk);

            WVPASS(2);

            // Doing it twice doesn't change anything.
            disk.Put(schema, sums, VxPutOpts.None);

            VerifyExportedSchema(tmpdir, schema, sums, sc, backup_generation, 
                base_filecounts);

            WVPASS(3);

            // Check backup mode
            disk.Put(schema, sums, VxPutOpts.IsBackup);
            backup_generation++;

            VerifyExportedSchema(tmpdir, schema, sums, sc, backup_generation, 
                base_filecounts);

            WVPASS(4);

            // Check backup mode again
            disk.Put(schema, sums, VxPutOpts.IsBackup);
            backup_generation++;

            VerifyExportedSchema(tmpdir, schema, sums, sc, backup_generation, 
                base_filecounts);

            WVPASS(5);
        }
        finally
        {
            tmpdirinfo.Delete(true);
            sc.Cleanup();
        }
	WVASSERT(!tmpdirinfo.Exists);
    }
Ejemplo n.º 13
0
    public void TestDropSchemaFromDisk()
    {
        string tmpdir = GetTempDir();
        try
        {
            Directory.CreateDirectory(tmpdir);
            VxDiskSchema backend = new VxDiskSchema(tmpdir);

            VxSchema schema = new VxSchema();
            schema.Add("Table", "Foo", "column: name=foo,type=int\n", false);
            schema.Add("Table", "Bar", "column: name=bar,type=int\n", false);
            schema.Add("Procedure", "Func1", "Func1 contents", false);
            schema.Add("ScalarFunction", "Func2", "Func2 contents", false);

            VxSchemaChecksums sums = new VxSchemaChecksums();
            sums.AddSum("Table/Foo", 1);
            sums.AddSum("Table/Bar", 2);
            sums.AddSum("Procedure/Func1", 3);
            sums.AddSum("ScalarFunction/Func2", 5);

            backend.Put(schema, sums, VxPutOpts.None);

            WVPASS(File.Exists(Path.Combine(tmpdir, "Table/Foo")));
            WVPASS(File.Exists(Path.Combine(tmpdir, "Table/Bar")));
            WVPASS(File.Exists(Path.Combine(tmpdir, "Procedure/Func1")));
            WVPASS(File.Exists(Path.Combine(tmpdir, "ScalarFunction/Func2")));

            VxSchema newschema = backend.Get(null);
            VxSchemaChecksums newsums = backend.GetChecksums();

            WVPASSEQ(newschema.Count, schema.Count);
            WVPASSEQ(newsums.Count, sums.Count);
            WVPASS(newschema.ContainsKey("Table/Foo"));
            WVPASS(newschema.ContainsKey("Table/Bar"));
            WVPASS(newschema.ContainsKey("Procedure/Func1"));
            WVPASS(newschema.ContainsKey("ScalarFunction/Func2"));

            string[] todrop = { "Table/Foo" };
            backend.DropSchema(todrop);

            WVPASS(!File.Exists(Path.Combine(tmpdir, "Table/Foo")))
            WVPASS(File.Exists(Path.Combine(tmpdir, "Table/Bar")))
            WVPASS(File.Exists(Path.Combine(tmpdir, "Procedure/Func1")))
            WVPASS(File.Exists(Path.Combine(tmpdir, "ScalarFunction/Func2")))

            newschema = backend.Get(null);
            newsums = backend.GetChecksums();
            WVPASSEQ(newschema.Count, 3);
            WVPASSEQ(newsums.Count, 3);
            WVPASS(!newschema.ContainsKey("Table/Foo"));
            WVPASS(newschema.ContainsKey("Table/Bar"));
            WVPASS(newschema.ContainsKey("Procedure/Func1"));
            WVPASS(newschema.ContainsKey("ScalarFunction/Func2"));

            todrop = new string[] { "Procedure/Func1", "ScalarFunction/Func2" };
            backend.DropSchema(todrop);

            WVPASS(!File.Exists(Path.Combine(tmpdir, "Table/Foo")))
            WVPASS(File.Exists(Path.Combine(tmpdir, "Table/Bar")))
            WVPASS(!File.Exists(Path.Combine(tmpdir, "Procedure/Func1")))
            WVPASS(!File.Exists(Path.Combine(tmpdir, "ScalarFunction/Func2")))

            newschema = backend.Get(null);
            newsums = backend.GetChecksums();
            WVPASSEQ(newschema.Count, 1);
            WVPASSEQ(newsums.Count, 1);
            WVPASS(!newschema.ContainsKey("Table/Foo"));
            WVPASS(newschema.ContainsKey("Table/Bar"));
            WVPASS(!newschema.ContainsKey("Procedure/Func1"));
            WVPASS(!newschema.ContainsKey("ScalarFunction/Func2"));
        }
        finally
        {
            Directory.Delete(tmpdir, true);
        }
	WVPASS(!Directory.Exists(tmpdir));
    }
Ejemplo n.º 14
0
    private void VerifyExportedSchema(string exportdir, VxSchema schema, 
        VxSchemaChecksums sums, SchemaCreator sc, int backupnum, 
        Dictionary<string, int> base_filecounts)
    {
        int filemultiplier = backupnum + 1;
        string suffix = backupnum == 0 ? "" : "-" + backupnum;

        string procdir = Path.Combine(exportdir, "Procedure");
        string scalardir = Path.Combine(exportdir, "ScalarFunction");
        string idxdir = Path.Combine(exportdir, "Index");
        string tabdir = Path.Combine(exportdir, "Table");
        string tabfuncdir = Path.Combine(exportdir, "TableFunction");
        string triggerdir = Path.Combine(exportdir, "Trigger");
        string viewdir = Path.Combine(exportdir, "View");
        string xmldir = Path.Combine(exportdir, "XMLSchema");

        WVPASSEQ(Directory.GetFiles(exportdir).Length, 0);
        WVPASS(Directory.Exists(procdir));
        WVPASS(Directory.Exists(scalardir));
        // We no longer store indexes in a separate directory; make sure 
        // that directory doesn't get created.
        WVPASS(!Directory.Exists(idxdir));
        WVPASS(Directory.Exists(tabdir));
        WVPASS(Directory.Exists(tabfuncdir));
        WVPASS(Directory.Exists(triggerdir));
        WVPASS(Directory.Exists(viewdir));
        WVPASS(Directory.Exists(xmldir));
        WVPASSEQ(Directory.GetDirectories(exportdir).Length, 7);

        Dictionary<string, int> filecounts = GetFileCounts(exportdir);

        // Procedures
        WVPASSEQ(Directory.GetDirectories(procdir).Length, 0);
        WVPASSEQ(filecounts["Procedure"], 
            (1 + base_filecounts["Procedure"]) * filemultiplier);
        string func1file = Path.Combine(procdir, "Func1" + suffix);
        CheckExportedFileContents(func1file, 
            "!!SCHEMAMATIC 2ae46ac0748aede839fb9cd167ea1180 0xd983a305 ",
            sc.func1q);

        // Scalar functions
        WVPASSEQ(Directory.GetDirectories(scalardir).Length, 0);
        WVPASSEQ(filecounts["ScalarFunction"], 
            (1 + base_filecounts["ScalarFunction"]) * filemultiplier);
        string func2file = Path.Combine(scalardir, "Func2" + suffix);
        CheckExportedFileContents(func2file, 
            "!!SCHEMAMATIC c7c257ba4f7817e4e460a3cef0c78985 0xd6fe554f ",
            sc.func2q);

        // Table-valued functions
        WVPASSEQ(Directory.GetDirectories(tabfuncdir).Length, 0);
        WVPASSEQ(filecounts["TableFunction"], 
            (1 + base_filecounts["TableFunction"]) * filemultiplier);
        string tabfunc1file = Path.Combine(tabfuncdir, "TabFunc1" + suffix);
        CheckExportedFileContents(tabfunc1file, 
            "!!SCHEMAMATIC 1d3f1392a80e44876254209feebe7860 0x4b96fbe4 ",
            sc.tabfuncq);

        // Tables
        WVPASSEQ(Directory.GetDirectories(tabdir).Length, 0);
        WVPASSEQ(filecounts["Table"], 
            (2 + base_filecounts["Table"]) * filemultiplier);

        string tab1file = Path.Combine(tabdir, "Tab1" + suffix);
        string tab2file = Path.Combine(tabdir, "Tab2" + suffix);

        WVPASS(File.Exists(tab1file));
        CheckExportedFileContents(tab1file, 
            "!!SCHEMAMATIC 72c64bda7c48a954e63f359ff1fa4e79 " + 
            sums["Table/Tab1"].GetSumString() + " ",
            sc.tab1sch);

        WVPASS(File.Exists(tab2file));
        CheckExportedFileContents(tab2file, 
            "!!SCHEMAMATIC 69b15b6da6961a0f006fa55106cb243b " +
            sums["Table/Tab2"].GetSumString() + " ", sc.tab2sch);

        // Triggers
        WVPASSEQ(Directory.GetDirectories(triggerdir).Length, 0);
        WVPASSEQ(filecounts["Trigger"], 
            (1 + base_filecounts["Trigger"]) * filemultiplier);
        string triggerfile = Path.Combine(triggerdir, "Trigger1" + suffix);
        CheckExportedFileContents(triggerfile, 
            "!!SCHEMAMATIC eb7556c49140340ff74f06660a55457b 0x5a93c375 ",
            sc.triggerq);

        // Views
        WVPASSEQ(Directory.GetDirectories(viewdir).Length, 0);
        WVPASSEQ(filecounts["View"], 
            (1 + base_filecounts["View"]) * filemultiplier);
        string viewfile = Path.Combine(viewdir, "View1" + suffix);
        CheckExportedFileContents(viewfile, 
            "!!SCHEMAMATIC b43a8c712d3a274a6842fc2413516665 0xe0af9ccd ",
            sc.viewq);

        // XML Schemas
        WVPASSEQ(Directory.GetDirectories(xmldir).Length, 0);
        WVPASSEQ(filecounts["XMLSchema"], 
            (1 + base_filecounts["XMLSchema"]) * filemultiplier);

        string testschemafile = Path.Combine(xmldir, "TestSchema" + suffix);
        WVPASS(File.Exists(testschemafile));
        CheckExportedFileContents(testschemafile, 
            "!!SCHEMAMATIC f45c4ea54c268c91f41c7054c8f20bc9 0xf4b2c764 ",
            sc.xmlq);

    }
Ejemplo n.º 15
0
    public void TestExportEmptySchema()
    {
        string tmpdir = GetTempDir();

        try 
        {
            Directory.CreateDirectory(tmpdir);

            VxSchema schema = new VxSchema();
            VxSchemaChecksums sums = new VxSchemaChecksums();

            // Check that exporting an empty schema doesn't touch anything.
            VxDiskSchema backend = new VxDiskSchema(tmpdir);
            backend.Put(schema, sums, VxPutOpts.None);
            WVPASSEQ(Directory.GetDirectories(tmpdir).Length, 0);
            WVPASSEQ(Directory.GetFiles(tmpdir).Length, 0);
        }
        finally
        {
            Directory.Delete(tmpdir);
        }
	WVASSERT(!Directory.Exists(tmpdir));
    }
Ejemplo n.º 16
0
    // Functions used for GetSchemaChecksums

    void GetProcChecksums(VxSchemaChecksums sums, 
            string type, int encrypted)
    {
        string encrypt_str = encrypted > 0 ? "-Encrypted" : "";

        log.print("Indexing: {0}{1}\n", type, encrypt_str);

        string query = @"
            select convert(varchar(128), object_name(id)) name,
                     convert(int, colid) colid,
                     convert(varchar(3900), text) text
                into #checksum_calc
                from syscomments
                where objectproperty(id, 'Is" + type + @"') = 1
                    and encrypted = @col0
                    and object_name(id) like '%'
            select name, convert(varbinary(8), getchecksum(text))
                from #checksum_calc
                order by name, colid
            drop table #checksum_calc";

        foreach (WvSqlRow row in DbiSelect(query, encrypted))
        {
            string name = row[0];

            // Ignore dt_* functions and sys* views
            if (name.StartsWith("dt_") || name.StartsWith("sys"))
                continue;

            ulong checksum = 0;
            foreach (byte b in (byte[])row[1])
            {
                checksum <<= 8;
                checksum |= b;
            }

            // Fix characters not allowed in filenames
            name.Replace('/', '!');
            name.Replace('\n', '!');
            string key = String.Format("{0}{1}/{2}", type, encrypt_str, name);

            log.print("name={0}, checksum={1}, key={2}\n", name, checksum, key);
            sums.AddSum(key, checksum);
        }
    }
Ejemplo n.º 17
0
    public VxSchemaChecksums GetChecksums()
    {
        WvDbusMsg call = methodcall("GetSchemaChecksums", "");

        WvDbusMsg reply = bus.send_and_wait(call);
	reply.check("a(sat)");
	VxSchemaChecksums sums = new VxSchemaChecksums(reply);
	return sums;
    }
Ejemplo n.º 18
0
    // Retrieves both the schema and its checksums from exportdir, and puts
    // them into the parameters.
    void ReadExportedDir(VxSchema schema, VxSchemaChecksums sums)
    {
        DirectoryInfo exportdirinfo = new DirectoryInfo(exportdir);
        if (exportdirinfo.Exists)
        {
            // Read all files that match */* and Index/*/*.
            foreach (DirectoryInfo dir1 in exportdirinfo.GetDirectories())
            {
                if (dir1.Name == "DATA")
                    continue;

                string type = dir1.Name;

                foreach (DirectoryInfo dir2 in dir1.GetDirectories())
                {
                    if (dir2.Name == "DATA" || dir1.Name != "Index")
                        continue;

                    // This is the Index/*/* part
                    foreach (FileInfo file in dir2.GetFiles())
                    {
                        if (!IsFileNameUseful(file.Name))
                            continue;

                        string name = wv.PathCombine(dir2.Name, file.Name);
                        AddFromFile(file.FullName, type, name, schema, sums);
                    }
                }

                // This is the */* part
                foreach (FileInfo file in dir1.GetFiles())
                {
                    if (!IsFileNameUseful(file.Name))
                        continue;

                    AddFromFile(file.FullName, type, file.Name, schema, sums);
                }
            }
        }
    }
Ejemplo n.º 19
0
    void GetTableChecksums(VxSchemaChecksums sums)
    {
        log.print("Indexing: Tables\n");

        // The weird "replace" in defval is because different versions of
        // mssql (SQL7 vs. SQL2005, at least) add different numbers of parens
        // around the default values.  Weird, but it messes up the checksums,
        // so we just remove all the parens altogether.
        string query = @"
            select convert(varchar(128), t.name) tabname,
               convert(varchar(128), c.name) colname,
               convert(varchar(64), typ.name) typename,
               convert(int, c.length) len,
               convert(int, c.xprec) xprec,
               convert(int, c.xscale) xscale,
               convert(varchar(128),
                   replace(replace(def.text, '(', ''), ')', ''))
                   defval,
               convert(int, c.isnullable) nullable,
               convert(int, columnproperty(t.id, c.name, 'IsIdentity')) isident,
               convert(int, ident_seed(t.name)) ident_seed,
               convert(int, ident_incr(t.name)) ident_incr
              into #checksum_calc
              from sysobjects t
              join syscolumns c on t.id = c.id 
              join systypes typ on c.xtype = typ.xtype
			           and c.xusertype = typ.xusertype
              left join syscomments def on def.id = c.cdefault
              where t.xtype = 'U'
                and typ.name <> 'sysname'
              order by tabname, c.colorder, colname, typ.status
           select tabname, convert(varbinary(8), getchecksum(tabname))
               from #checksum_calc
           drop table #checksum_calc";

        foreach (WvSqlRow row in DbiSelect(query))
        {
            string name = row[0];
            ulong checksum = 0;
            foreach (byte b in (byte[])row[1])
            {
                checksum <<= 8;
                checksum |= b;
            }

            // Tasks_#* should be ignored
            if (name.StartsWith("Tasks_#")) 
                continue;

            string key = String.Format("Table/{0}", name);

            log.print("name={0}, checksum={1}, key={2}\n", name, checksum, key);
            sums.AddSum(key, checksum);
        }
    }
Ejemplo n.º 20
0
    // Helper method to load a given on-disk element's schema and checksums
    // into the container objects.
    // Throws an ArgumentException if the schema or sums already contains the
    // given key.
    static void AddFromFile(string path, string type, string name, 
        VxSchema schema, VxSchemaChecksums sums)
    {
        string key = wv.fmt("{0}/{1}", type, name);

        // schema/sums.Add would throw an exception in this situation anyway, 
        // but it's nice to provide a more helpful error message.
        if (schema != null && schema.ContainsKey(key))
            throw new ArgumentException("Conflicting schema key: " + key);
        if (sums != null && sums.ContainsKey(key))
            throw new ArgumentException("Conflicting sums key: " + key);

        VxSchemaChecksum sum;
        VxSchemaElement elem;
        ReadSchemaFile(path, type, name, out elem, out sum);

        if (schema != null && elem != null)
            schema.Add(key, elem);
        if (sums != null && sum != null)
            sums.Add(key, sum);
    }
Ejemplo n.º 21
0
    void AddIndexChecksumsToTables(VxSchemaChecksums sums)
    {
        string query = @"
            select 
               convert(varchar(128), object_name(i.object_id)) tabname,
               convert(varchar(128), i.name) idxname,
               convert(int, i.type) idxtype,
               convert(int, i.is_unique) idxunique,
               convert(int, i.is_primary_key) idxprimary,
               convert(varchar(128), c.name) colname,
               convert(int, ic.index_column_id) colid,
               convert(int, ic.is_descending_key) coldesc
              into #checksum_calc
              from sys.indexes i
              join sys.index_columns ic
                 on ic.object_id = i.object_id
                 and ic.index_id = i.index_id
              join sys.columns c
                 on c.object_id = i.object_id
                 and c.column_id = ic.column_id
              where object_name(i.object_id) not like 'sys%' 
                and object_name(i.object_id) not like 'queue_%'
              order by i.name, i.object_id, ic.index_column_id
              
            select
               tabname, idxname, colid, 
               convert(varbinary(8), getchecksum(idxname))
              from #checksum_calc
            drop table #checksum_calc";

        foreach (WvSqlRow row in DbiSelect(query))
        {
            string tablename = row[0];
            string indexname = row[1];
            ulong checksum = 0;
            foreach (byte b in (byte[])row[3])
            {
                checksum <<= 8;
                checksum |= b;
            }

            string key = String.Format("Table/{0}", tablename);

            log.print("tablename={0}, indexname={1}, checksum={2}, colid={3}\n", 
                tablename, indexname, checksum, (int)row[2]);
            sums.AddSum(key, checksum);
        }
    }
Ejemplo n.º 22
0
 public void TestChecksumEquality(VxSchemaChecksums left, 
     VxSchemaChecksums right)
 {
     WVPASSEQ(left.Count, right.Count);
     foreach (KeyValuePair<string,VxSchemaChecksum> p in right)
     {
         WVPASSEQ(left[p.Key].GetSumString(), p.Value.GetSumString());
     }
 }
Ejemplo n.º 23
0
    public void TestChecksumDiff()
    {
        VxSchemaChecksums srcsums = new VxSchemaChecksums();
        VxSchemaChecksums goalsums = new VxSchemaChecksums();
        VxSchemaChecksums emptysums = new VxSchemaChecksums();

        srcsums.AddSum("XMLSchema/secondxml", 2);
        srcsums.AddSum("XMLSchema/firstxml", 1);
        srcsums.AddSum("Procedure/ConflictProc", 3);
        srcsums.AddSum("Table/HarmonyTable", 6);

        goalsums.AddSum("Table/NewTable", 3);
        goalsums.AddSum("Procedure/NewFunc", 4);
        goalsums.AddSum("Procedure/ConflictProc", 5);
        goalsums.AddSum("Table/HarmonyTable", 6);

        VxSchemaDiff diff = new VxSchemaDiff(srcsums, goalsums);

        string expected = "- XMLSchema/firstxml\n" + 
            "- XMLSchema/secondxml\n" +
            "+ Table/NewTable\n" +
            "* Procedure/ConflictProc\n" +
            "+ Procedure/NewFunc\n";
        WVPASSEQ(diff.ToString(), expected);

        // Check that the internal order matches the string's order.
        WVPASSEQ(diff.ElementAt(0).Key, "XMLSchema/firstxml");
        WVPASSEQ(diff.ElementAt(1).Key, "XMLSchema/secondxml");
        WVPASSEQ(diff.ElementAt(2).Key, "Table/NewTable");
        WVPASSEQ(diff.ElementAt(3).Key, "Procedure/ConflictProc");
        WVPASSEQ(diff.ElementAt(4).Key, "Procedure/NewFunc");

        // Check that a comparison with an empty set of sums returns the other
        // side, sorted.
        diff = new VxSchemaDiff(srcsums, emptysums);
        expected = "- XMLSchema/firstxml\n" + 
            "- XMLSchema/secondxml\n" + 
            "- Table/HarmonyTable\n" + 
            "- Procedure/ConflictProc\n";
        WVPASSEQ(diff.ToString(), expected);

        diff = new VxSchemaDiff(emptysums, goalsums);
        expected = "+ Table/HarmonyTable\n" +
            "+ Table/NewTable\n" +
            "+ Procedure/ConflictProc\n" +
            "+ Procedure/NewFunc\n";
        WVPASSEQ(diff.ToString(), expected);
    }