ジャナ・ビジネス・コンサルティング有限会社トップページへ
/*
 * Berkeley DB XML .NET API
 * 
 * Copyright (C) 2007 Jana Business Consulting Ltd. All rights reserved.
 * 
 * For more information, see http://www.janabiz.com.
 * 
 */

using JanaBiz.Db;
using JanaBiz.DbXml;
using JanaBiz.DbXml.Exceptions;

public class MutilProcessCmd
{
    private static string theContainer = "namespaceExampleData.dbxml";
    
    public static void Main(string[] args)
    {
        MutilProcessCmd mutilProcessCmd = new MutilProcessCmd();
        System.Console.WriteLine("args.Length=" + args.Length);
        for(int i = 0;i < args.Length; i++)
        {
            System.String path = args[i]; 
            System.Console.WriteLine("   args[" + i + "]" + path);
        }
        string cmd = parseArguments(args);
        
        //string cmd = "2";
        System.Console.WriteLine(theContainer);
        
        System.Console.WriteLine("Comand=" + cmd[0] + ";");    
        switch(cmd[0])
        {
            case '1':
                mutilProcessCmd.doQuery(@"..\..\");
				break;
			case '2':
				mutilProcessCmd.doUpdate(@"..\..\","2");
				break;
			case '3':
				mutilProcessCmd.doUpdate(@"..\..\","3");
				break;
			default: 
				System.Console.WriteLine("Unknown command option: " + cmd);
				break;
		}
	}
	
	#region query
	// Performs a query against a document using an QueryContext.
	private void doContextQuery(XmlManager mgr, string query, 
		XmlQueryContext context)
	{
		// Perform a single query against the referenced container using
		// the referenced context.
		System.Console.WriteLine("Exercising query: '" + query + "'.");
		System.Console.WriteLine("Return to continue: ");
		//System.Console.ReadLine();
	
		// Perform the query
		XmlResults results = mgr.Query(null, query, context, new XmlDocumentConfig());
		// Iterate over the results
		while(results.MoveNext())
		{
			//System.Console.WriteLine(results.Current);
			using(XmlDocument doc = results.Current.ToDocument()) 
			{
				System.Console.WriteLine("    DocumentName=" + doc.Name);
			}
		}
		System.Console.WriteLine(results.Size + " results returned for query '" 
			+ query + "'.");
	}

	public void doQuery(string envdir) 
	{
		DbEnvironment dbEnv = null;
		XmlManager mgr = null;
		XmlContainer container = null;
		System.Console.Write("doQuery()");
		
		try 
		{
			// Open an environment 
			dbEnv = CreateDbEnvironment(envdir);
			
			// Open a manager
			using(mgr = CreateManager(dbEnv)) 
			{

				// Open a transactional container
				XmlContainerConfig containerconfig = new XmlContainerConfig();
				containerconfig.Transactional = true;
				using(container = mgr.OpenContainer(null, theContainer,
					containerconfig))
				{

					// Create a context and declare the namespaces
					using(XmlQueryContext context = mgr.CreateQueryContext()) 
					{
						context.SetNamespace("fruits", "http://groceryItem.dbxml/fruits");
                        context.SetNamespace("vegetables", "http://groceryItem.dbxml/vegetables");
                        context.SetNamespace("desserts", "http://groceryItem.dbxml/desserts");

                        // Set a variable
                        context.SetVariableValue("aDessert",
                            new XmlValue("Blueberry Boy Bait"));

                        // Perform the queries

                        // Find all the Vendor documents in the database. Vendor documents do
                        // not use namespaces, so this query returns documents.
                        doContextQuery(mgr, "collection(\"" + theContainer +
                            "\")/vendor", context);

                        // Find the product document for "Lemon Grass". 
                        // This query returns no documents
                        // because a namespace prefix is not identified for the 'item' node.
                        doContextQuery(mgr, "collection(\"" + theContainer +
                            "\")/item/product[.=\"Lemon Grass\"]", context);

                        // Find the product document for "Lemon Grass" using the namespace 
                        // prefix 'fruits'. This query successfully returns a document.
                        doContextQuery(mgr, "collection(\"" + theContainer +
                            "\")/fruits:item/product[.=\"Lemon Grass\"]", context);

                        // Find all the vegetables
                        doContextQuery(mgr, "collection(\"" + theContainer +
                            "\")/vegetables:item", context);

                        // Find the dessert called Blueberry Boy Bait.
                        // Note the use of a variable.
                        doContextQuery(mgr, "collection(\"" + theContainer +
                            "\")/desserts:item/product[.=$aDessert]", context);
                    }
                }
            }
        }
        catch(DbXmlException e) 
        {
            System.Console.WriteLine("Error performing query against " + theContainer);
            System.Console.WriteLine(e.ToString());
        }
        finally
        {
            if(container != null)
            {
                container.Close();
            }
            if(mgr != null)
            {
                mgr.Close();
            }
            if(dbEnv != null)
            {
                dbEnv.Close();
            }
        }
    }
    #endregion query
    
    #region doUpdate
    
    // Method to add a "description" element after the query's target nodes
    private  void doModify(XmlManager mgr, XmlContainer container, XmlQueryContext context,
        string query, XmlTransaction txn,string updateValue,int updateCount) 
    {

        using(XmlQueryExpression expression = mgr.Prepare(txn, query, context)) 
        {
       
            System.Console.WriteLine("Updating document for the expression: '" + 
                query + "' ");
            System.Console.WriteLine("Return to continue: ");
            //System.Console.ReadLine();
        
            // Print the document(s) to be updated -- those that describe 
            // Zapote Blanco (a fruit). The document strings are only being 
            // printed to show before/after results.
            // Most modification programs would not perform the additional queries.
            using(XmlResults results = expression.Execute(txn, context, new XmlDocumentConfig())) 
            {
                //dumpDocuments(results);
      
                results.Reset();

                System.Console.WriteLine("About to update the document(s) above.");
                System.Console.WriteLine("Look for a new element after the target " +
                    "element, named 'description' ...");
                System.Console.WriteLine("Return to continue: ");
                //System.Console.ReadLine();
       
                // The modification is a new element in the target node, called 
                // "descripton, which goes immediately after the <product> element.
                // if this program is run more than once, and committed, additional
                // identical elements are added.  It is easy to modify this program
                // to change the modification.
                using(XmlModify modify = mgr.CreateModify()) 
                {
                    using(XmlQueryExpression subexpr = mgr.Prepare(txn, ".", context)) 
                    {
                        string descriptionValue = "cmd=" + updateValue + ";i=" + updateCount + ";";
                        modify.AddInsertAfterStep(subexpr, XmlModifyXmlObject.Element, "cmd"+updateValue ,descriptionValue);

                        using(XmlUpdateContext uc = mgr.CreateUpdateContext()) 
                        {
                            long numMod = modify.Execute(txn, results, context, uc);
        
                            System.Console.WriteLine("Performed " + numMod + " modification operations");
                            dumpDocuments(results);
                        }
                    }
                }
            }
        }
    }

    // display documents matching the query
    private void dumpDocuments(XmlResults results) 
    {
        System.Console.WriteLine("Found " + results.Size + " documents ");
        
        results.Reset();
        while(results.MoveNext()) 
        {
            using(XmlDocument doc = results.Current.ToDocument()) 
            {
                System.Console.WriteLine("Document content: ");
                System.Console.WriteLine(doc.StringContent);
            }
        }
    }
    
    public void doUpdate(string envdir,string cmd) 
    {
        /**
		System.String[] dirs = System.IO.Directory.GetDirectories(envdir); 
		foreach(System.String path in dirs)
		{
			System.Console.WriteLine(path);
		}
		**/
        
        DbEnvironment dbEnv = null;
        XmlManager mgr = null;
        XmlContainer container = null;
        
        try 
        {
            // Open an environment
            dbEnv = CreateDbEnvironment(envdir);
            
            // Open a manager
            using(mgr = CreateManager(dbEnv)) 
            {
                // Open a transactional container
                XmlContainerConfig containerconfig = new XmlContainerConfig();
                containerconfig.Transactional = true;
                using(container = mgr.OpenContainer(null, theContainer,
                    containerconfig)) 
                {
                    for(int updateCount = 0; updateCount < 15; updateCount++)
                    {
                        // Start a transaction
                        using(XmlTransaction txn = mgr.CreateTransaction())
                        {
                            // Create a context and declare the namespaces
                            using(XmlQueryContext context = mgr.CreateQueryContext()) 
                            {
                                context.SetNamespace("fruits", "http://groceryItem.dbxml/fruits");
                                context.SetNamespace("vegetables", "http://groceryItem.dbxml/vegetables");
                                context.SetNamespace("desserts", "http://groceryItem.dbxml/desserts");
        
                                // Modify the document that describes "Zapote Blanco" (a fruit)
                                string query = null;
                                if("2".Equals(cmd))
                                {
                                     query = "collection(\"" + theContainer + "\")/fruits:item/product[. = 'Zapote Blanco']";
                                }
                                else
                                {
                                    query = "collection(\"" + theContainer + "\")/fruits:item/vendor[. = 'Off the Vine']";
                                }

                                doModify(mgr, container, context, query, txn,cmd,updateCount);

                                txn.Commit();
                                /**
								System.Console.WriteLine("If committed, this program will add a new element each time it is run.");
								System.Console.WriteLine("Press 'c' to commit this change:");
							
								int c = System.Console.Read();
								if (c == (int)'c' || c == (int)'C')
									txn.Commit();
								else
									txn.Rollback();
								**/
                            }
                        }
                    }
                }
            }
        }
        catch(DbXmlException e) 
        {
            System.Console.WriteLine("Error performing document modification against " + theContainer);
            System.Console.WriteLine(e.ToString());
        }
        finally
        {
            if(container != null)
            {
                container.Close();
            }
            if(mgr != null)
            {
                mgr.Close();
            }
            if(dbEnv != null)
            {
                dbEnv.Close();
            }
        }
    }
    #endregion
    
    #region common config
    public DbEnvironment CreateDbEnvironment(string envdir) 
    {
        DbEnvironmentConfig envconf = new DbEnvironmentConfig();
        envconf.CacheSize = 50 * 1024;
        envconf.AllowCreate = true;    
        envconf.InitializeCache = true;
        envconf.Transactional = true;
        envconf.InitializeLocking = true;
        envconf.InitializeLogging = true;
        envconf.RunRecovery = true;
        envconf.ErrorWriter = System.Console.Out;
        envconf.ErrorPrefix = "PREFIX"; 
        
        envconf.Private = true;

        DbEnvironment env = new DbEnvironment(envdir, envconf);
        
        return env;
    }

    public XmlManager CreateManager(DbEnvironment env) 
    {
        XmlManagerConfig mgrconfig = new XmlManagerConfig();
        mgrconfig.AdoptEnvironment = true;
        try 
        {
            return new XmlManager(env, mgrconfig);
        }
        catch(System.Exception e) 
        {
            env.Close();
            throw e;
        }
    }
    
    #endregion common config
    
    private static string parseArguments(string[] args) 
    {
        string cmd = null;
        for(int i = 0; i < args.Length; ++i) 
        {
            string arg = args[i];
            if((arg.StartsWith("-")
#if WIN32
                || arg.StartsWith("/")
#endif
                ) && arg.Length > 1) 
            {
                switch(arg[1]) 
                {
                    case 'c': 
                    {
                        ++i;
                        if(i >= args.Length) 
                        {
                            System.Console.WriteLine("Invalid option: " + arg);
                            Usage();
                        }
                        cmd = args[i];
                        break;
                    }
                    default: 
                    {
                        System.Console.WriteLine("Unknown option: " + arg);
                        Usage();
                        break;
                    }
                }
            }
            else 
            {
                System.Console.WriteLine("Too many arguments: " + arg);
                Usage();
            }
        }
        if(cmd == null) 
        {
            System.Console.WriteLine("Environment directory not found.");
            Usage();
        }
        return cmd;
    }
    private static void Usage() 
    {
        System.Console.WriteLine("This program modifies documents found in a DBXML container.");
        System.Console.WriteLine("You should run exampleLoadContainer before running this example.");
        System.Console.WriteLine("You are only required to pass this command the path location of the");
        System.Console.WriteLine("database environment that you specified when you loaded the examples data:");
        System.Console.WriteLine();
        System.Console.WriteLine("\t-c <cmd 1,2,3>");
        System.Console.WriteLine("For example:");
        System.Console.WriteLine("\tmodifyDocument.exe -c 1");

        System.Environment.Exit(-1);
    }

}