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

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

public class ReplaceIndex
{
    private static string theContainer = "namespaceExampleData.dbxml";

    // Method used to replace an index with a new index type
    private static void replaceIndex(XmlManager mgr, XmlContainer container,
                                     string URI, string nodeName, string indexType, XmlTransaction txn)
    {
        Console.WriteLine("Replacing index specification '" + indexType +
                          "' from node '" + nodeName + "'.");

        // Retrieve the index specification from the container
        using (XmlIndexSpecification idxSpec = container.GetIndexSpecification(txn)) {
            // See what indexes exist on the container
            int count = 0;
            Console.WriteLine("Before index replacement:");
            // Loop over the indexes and report what's there.
            while (idxSpec.MoveNext()) {
                Console.WriteLine("\tFor node '" + idxSpec.Current.Name +
                                  "', found index: '" + idxSpec.Current.Index + "'.");
                ++count;
            }
            Console.WriteLine(count + " indexes found.");

            // Replace the container's index specification with a new specification
            idxSpec.ReplaceIndex(URI, nodeName, indexType);

            // Get an update context.
            using (XmlUpdateContext updateContext = mgr.CreateUpdateContext()) {
                // Set the specification back to the container
                container.SetIndexSpecification(txn, idxSpec, updateContext);
            }
        }

        // Retrieve the index specification from the container
        using (XmlIndexSpecification idxSpec = container.GetIndexSpecification(txn)) {
            // Look at the indexes again to make sure our deletion took.
            int count = 0;
            Console.WriteLine("After index replacement:");
            while (idxSpec.MoveNext()) {
                Console.WriteLine("\tFor node '" + idxSpec.Current.Name +
                                  "', found index: '" + idxSpec.Current.Index + "'.");
                ++count;
            }
            Console.WriteLine(count + " indexes found.");
        }
    }

    public static void Main(string[] args)
    {
        string envdir = parseArguments(args);

        DbEnvironment dbEnv = null;
        XmlManager mgr = null;
        XmlContainer container = null;

        try {
            // Open an environment
            dbEnv = CreateDbEnvironment(envdir);

            // Open an environment and manager
            using (mgr = CreateManager(dbEnv)) {
                // Open a transactional container
                XmlContainerConfig containerconfig = new XmlContainerConfig();
                containerconfig.Transactional = true;
                using (container = mgr.OpenContainer(null, theContainer,
                                                     containerconfig)) {
                    // Start a transaction
                    using (XmlTransaction txn = mgr.CreateTransaction()) {
                        // Replace the index on the "product" node.
                        replaceIndex(mgr, container, "", "product",
                                     "node-attribute-substring-string node-element-equality-string",
                                     txn);
                        // Commit the index replacement
                        txn.Commit();
                    }
                }
            }
        } catch (DbXmlException e) {
            Console.WriteLine("Error replacing index for container " + theContainer);
            Console.WriteLine(e.ToString());
        } finally {
            if (container != null) {
                container.Close();
            }
            if (mgr != null) {
                mgr.Close();
            }
            if (dbEnv != null) {
                dbEnv.Close();
            }
        }
    }

    public static 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 = Console.Out;
        envconf.ErrorPrefix = "LOG";

        DbEnvironment env = new DbEnvironment(envdir, envconf);

        return env;
    }

    public static XmlManager CreateManager(DbEnvironment env)
    {
        XmlManagerConfig mgrconfig = new XmlManagerConfig();
        mgrconfig.AdoptEnvironment = true;
        try {
            return new XmlManager(env, mgrconfig);
        } catch (Exception e) {
            env.Close();
            throw e;
        }
    }

    private static void Usage()
    {
        Console.WriteLine("This program replaces a DB XML container's index specification with a new");
        Console.WriteLine("specification. You should run exampleLoadContainer before running this example.");
        Console.WriteLine("You are only required to pass this command the path location of the database");
        Console.WriteLine("environment that you specified when you loaded the examples data:");
        Console.WriteLine();
        Console.WriteLine("\t-h <dbenv directory>");
        Console.WriteLine();
        Console.WriteLine("For best results, run addIndex before running this program.");
        Console.WriteLine();
        Console.WriteLine("For example:");
        Console.WriteLine("\treplaceIndex.exe -h examplesEnvironment");

        Environment.Exit(-1);
    }

    private static string parseArguments(string[] args)
    {
        string envdir = 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 'h':
                        {
                            ++i;
                            if (i >= args.Length) {
                                Console.WriteLine("Invalid option: " + arg);
                                Usage();
                            }
                            envdir = args[i];
                            break;
                        }
                    default:
                        {
                            Console.WriteLine("Unknown option: " + arg);
                            Usage();
                            break;
                        }
                }
            } else {
                Console.WriteLine("Too many arguments: " + arg);
                Usage();
            }
        }
        if (envdir == null) {
            Console.WriteLine("Environment directory not found.");
            Usage();
        }
        return envdir;
    }
}