예제 #1
0
파일: sm.cs 프로젝트: apenwarr/versaplex
    static int do_push(ISchemaBackend remote, string dir, VxCopyOpts opts)
    {
        log.print("Pushing schema.\n");
        VxDiskSchema disk = new VxDiskSchema(dir);

        VxSchemaErrors errs = VxSchema.CopySchema(disk, remote, opts);

	int code = 0;
        foreach (var p in errs)
	{
            foreach (var err in p.Value)
            {
                Console.WriteLine("{0} applying {1}: {2} ({3})", 
                    err.level, err.key, err.msg, err.errnum);
                code = 1;
            }
	}
	
	return code;
    }
예제 #2
0
파일: sm.cs 프로젝트: apenwarr/versaplex
    static int do_dpush(ISchemaBackend remote, string dir, VxCopyOpts opts)
    {
        log.print("Pushing data.\n");
	
        if (!Directory.Exists(dir))
            return 5; // nothing to do

        string datadir = Path.Combine(dir, "DATA");
        if (Directory.Exists(datadir))
	    dir = datadir;
	
	var files = 
	    from f in Directory.GetFiles(dir)
	    where !f.EndsWith("~")
	    select f;
	return ApplyFiles(files.ToArray(), remote, opts);
    }
예제 #3
0
파일: sm.cs 프로젝트: apenwarr/versaplex
    static int do_dpull(ISchemaBackend remote, string dir,
			 VxCopyOpts opts)
    {
        log.print("Pulling data.\n");

        string cmdfile = Path.Combine(dir, "data-export.txt");
        if (!File.Exists(cmdfile))
        {
            err.print("Missing command file: {0}\n", cmdfile);
            return 5;
        }

        log.print("Retrieving schema checksums from database.\n");
        VxSchemaChecksums dbsums = remote.GetChecksums();

        log.print("Reading export commands.\n");
        string[] cmd_strings = File.ReadAllLines(cmdfile);
        
        Dictionary<string,string> replaces = new Dictionary<string,string>();
        List<string> skipfields = new List<string>();
        string tablefield, replacewith;
        int i = 0;
        foreach (string s in cmd_strings)
        {
            if (s.StartsWith("replace "))
            {
                //take replace off
                replacewith = s.Substring(8);
                
                //take table.fieldname
                tablefield = replacewith.Substring(0,
                                    s.IndexOf(" with ")-8).Trim().ToLower();
                
                //take the value
                replacewith = replacewith.Substring(
                                    replacewith.IndexOf(" with ")+6).Trim();
                if (replacewith.ToLower() == "null")
                    replaces.Add(tablefield,null);
                else
                    replaces.Add(tablefield,
                               replacewith.Substring(1,replacewith.Length-2));
                
                cmd_strings[i] = "";
            }
            else if (s.StartsWith("skipfield "))
            {
                skipfields.Add(s.Substring(10).Trim().ToLower());
                cmd_strings[i] = "";
            }
                
            i++;
        }

        log.print("Parsing commands.\n");
        IEnumerable<Command> commands = ParseCommands(cmd_strings);

        foreach (Command cmd in commands)
        {
            if (cmd.cmd != "zap" && !dbsums.ContainsKey("Table/" + cmd.table))
            {
                err.print("Table doesn't exist: {0}\n", cmd.table);
                return 4;
            }
        }

        if (commands == null)
            return 3;

        string datadir = Path.Combine(dir, "DATA");
        log.print("Cleaning destination directory '{0}'.\n", datadir);
        Directory.CreateDirectory(datadir);
        foreach (string path in Directory.GetFiles(datadir, "*.sql"))
        {
            if ((opts & VxCopyOpts.DryRun) != 0)
                log.print("Would have deleted '{0}'\n", path);
            else
                File.Delete(path);
        }

        log.print("Processing commands.\n");
        foreach (Command cmd in commands)
        {
            StringBuilder data = new StringBuilder();
            if (cmd.cmd == "export")
            {
                data.Append(wv.fmt("TABLE {0}\n", cmd.table));
                data.Append(remote.GetSchemaData(cmd.table, cmd.pri, cmd.where,
                                                 replaces, skipfields));
            }
            else if (cmd.cmd == "export-nosort")
            {
		//TODO: dry-run!
                FileStream f = new FileStream(Path.Combine(datadir,
                               wv.fmt("{0:d5}-{1}.cql", cmd.pri, cmd.table)),
                               FileMode.OpenOrCreate, FileAccess.Write);
                StreamWriter sw = new StreamWriter(f);
                sw.Write(wv.fmt("TABLE {0}\n", cmd.table));
                remote.WriteSchemaData(sw, cmd.table, cmd.pri, cmd.where, 
                                       replaces, skipfields);
                sw.Close();
                f.Close();
                continue;
            }
            else if (cmd.cmd == "zap")
            {
                foreach (string table in cmd.table.Split(whitespace, 
                    StringSplitOptions.RemoveEmptyEntries))
                {
                    if (table != "*")
                        data.Append(wv.fmt("DELETE FROM [{0}]\n\n", table));
                    else
                    {
                        List<string> todelete = new List<string>();
                        foreach (var p in dbsums)
                        {
                            string type, name;
                            VxSchema.ParseKey(p.Value.key, out type, out name);
                            if (type == "Table")
                                todelete.Add(name);
                        }
                        todelete.Sort(StringComparer.Ordinal);
                        foreach (string name in todelete)
                            data.Append(wv.fmt("DELETE FROM [{0}]\n", name));
                    }
                }
                cmd.table = "ZAP";
            }
      
            string outname = Path.Combine(datadir, 
                wv.fmt("{0:d5}-{1}.sql", cmd.pri, cmd.table));

            if ((opts & VxCopyOpts.DryRun) != 0)
                log.print("Would have written '{0}'\n", outname);
            else
                File.WriteAllBytes(outname, data.ToString().ToUTF8());
        }
	
	return 0;
    }
예제 #4
0
파일: sm.cs 프로젝트: apenwarr/versaplex
    static int ApplyFiles(string[] files, ISchemaBackend remote,
			  VxCopyOpts opts)
    {
        int seqnum = 0;
        string tablename = "";

        Array.Sort(files);
        foreach (string file in files)
        {
            string data = File.ReadAllText(file, Encoding.UTF8);
            VxDiskSchema.ParsePath(file, out seqnum, out tablename);

            if (tablename == "ZAP")
                tablename = "";

            log.print("Applying data from {0}\n", file);
            if ((opts & VxCopyOpts.DryRun) != 0)
                continue;

            if (seqnum > 0)
            {
                remote.PutSchemaData(tablename, data, seqnum);
            }
            else
            {
                // File we didn't generate, try to apply it anyway.
                remote.PutSchemaData("", data, 0);
            }
        }
	
	return 0;
    }
예제 #5
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();
    }