[seasar-dotnet:1008] Re: 動的に複数DBファイルを作成して、複数同時にアクセス

Yoshihiro OSHITA [E-MAIL ADDRESS DELETED]
2008年 10月 19日 (日) 11:46:07 JST


小谷様、
お世話になっています、大下です。
お忙しいところ、詳細な説明をつけていただき、恐縮しております。ありがとうございます。
(投稿しようとしたところ、メールが長すぎるとMLシステムに怒られたので、いままでのやりとりを削除しております。ご了承ください。)

>とりあえず"動的な接続"の要件は基本的にこの二つ、ですよね?
>1.テーブル構造は固定
>2.接続先は最初は存在しない(動的に追加してやる必要がある)

はい、その通りです。
この要件をもっとはっきり提示するべきでした、すみません。

小谷さんから返信をいただく前に、検証コードを書いておりました。
結果から申し上げると、私が書いた検証コードはまだうまく動作しておりません。

Diconの設定内容やSelectableDataSourceProxyWithDictionaryクラスのソースを読んでみて、こういう処理を書けばよいのかなぁと想像して書いたコードと、小谷さんからいただいた説明がだいたい同じであるので、大まかな流れはあっているとは思うのですが…。
全体的なソースコードを貼ってしまいたいのですが、ちょっと長くなりそうなので、部分的に質問させていただきますと、

> この「IDataSource実装クラスのインスタンス(データソース)」が
> 大下さん側で作っていただくことになる部分になります。
> (TxDataSourceもIDataSourceを実装しているクラスです)

これについて、以下のようなコードを書いてみました。
---------------
    class TxSetupper
    {
        private SelectableDataSourceProxyWithDictionary _dsProxy;

        public SelectableDataSourceProxyWithDictionary DSProxy
        {
            get { return _dsProxy; }
            set { _dsProxy = value; }
        }

        public String CreateTxDataSource()
        {
            // 接続文字列を作成する
            SQLiteConnectionStringBuilder conn = new
SQLiteConnectionStringBuilder();

              // 一意なDBファイル名をここで作成
            String strDBName = Guid.NewGuid().ToString();
            conn.DataSource = strDBName + ".SQ3";
            conn.FailIfMissing = false;
            conn.SyncMode = SynchronizationModes.Normal;
            conn.DateTimeFormat = SQLiteDateFormats.ISO8601;
            conn.CacheSize = 2000;
            conn.PageSize = 1024;
            conn.LegacyFormat = true;
            conn.DefaultTimeout = 30;

            // データプロバイダ
            DataProvider dp = new DataProvider();
            dp.ConnectionType = "System.Data.SQLite.SQLiteConnection";
            dp.CommandType = "System.Data.SQLite.SQLiteCommand";
            dp.ParameterType = "System.Data.SQLite.SQLiteParameter";
            dp.DataAdapterType = "System.Data.SQLite.SQLiteDataAdapter";

            // データソース作成
            IDataSource dataSource = new TxDataSource(dp, conn.ToString());
            _dsProxy.RegistDataSource(strDBName, dataSource);

            //  TransactionContext
            TransactionContext txContext = new TransactionContext();
            txContext.DataSouce = dataSource;
            txContext.IsolationLevel = IsolationLevel.ReadCommitted;

            //  TransactionContextを使用するデータソースにも設定
            Type dataSourceType = dataSource.GetType();
            if
(typeof(SelectableDataSourceProxyWithDictionary).IsAssignableFrom(
                dataSourceType))
            {

((SelectableDataSourceProxyWithDictionary)dataSource).SetTransactionContext(
                    txContext);
            }
            else if (typeof(TxDataSource).IsAssignableFrom(dataSourceType))
            {
                ((TxDataSource)dataSource).Context = txContext;
            }

            //  TransactionInterceptor
            LocalRequiredTxHandler handler = new LocalRequiredTxHandler();
            handler.Context = txContext;
            IMethodInterceptor _transactionInterceptor = new
TransactionInterceptor(handler);

((TransactionInterceptor)_transactionInterceptor).TransactionStateHandler
                = txContext;

            return strDBName;
        }
    }
---------------
こんな感じで合っていますでしょうか?
このTxSetupperクラスのTxSetupper#CreateTxDataSourceメソッドを呼んだあとで、

> 追加したデータソースを使いたい場合は
> SelectableDataSourceProxyWithDictionary#SetDataSourceNameメソッドを呼び、
> 引数にRegisterDataSourceで設定したデータソース名を指定して下さい。

をやり、Daoで定義したメソッドを呼んでいます。(下記のとおり)
---------------
    class Program
    {
        static void Main(string[] args)
        {
            QuillInjector injector = QuillInjector.GetInstance();

            LibraryLogic logic = new LibraryLogic();
            TxSetupper txSetup = new TxSetupper();

            injector.Inject(logic);
            injector.Inject(txSetup);

            String strDBName = txSetup.CreateTxDataSource();
            txSetup.DSProxy.SetDataSourceName(strDBName);
            bool bContains
                =
txSetup.DSProxy.DataSourceCollection.ContainsKey(strDBName);

            Library lib = new Library("TestLib", "Foo");

            logic.Dao.Insert(lib);
        }
    }
---------------
ここで、LibraryLogicクラスは、
---------------
    [Implementation]
    class LibraryLogic
    {
        private ILibraryDao _dao;

        public ILibraryDao Dao
        {
            get { return _dao; }
            set { _dao = value; }
        }

        public int Insert(Library lib)
        {
            Console.WriteLine("▽Insert実行します");
            return _dao.Insert(lib);
        }
    }
--------------------
のようになっており、Daoは、
--------------------
    [Implementation]    [Bean(typeof(Library))]
    public interface ILibraryDao
    {
        [S2Dao]
        [Transaction]
        int Insert(Library library);
    }
--------------------
となっております。
#結局、ほとんどソース貼っちゃった…

>すいません。
>私、ずっとQuillを使うこと前提に話をしてしまっていますね。

はは、
正直、S2Container.NET?Quill?とちょっと私も混乱しているのですが、Quillを使えってことなのかなぁと、なんとなく理解しています。
おまけにAOPやDIも今回触れるのが始めてなので、かなり素っ頓狂な質問を繰り返しているような気がするのですが、ご容赦ください。
お忙しいのにすみません、長くなりましたが上記で質問したことに何か回答をいただけると幸いです。
-------------- next part --------------
HTMLの添付ファイルを保管しました...
URL: <http://ml.seasar.org/archives/seasar-dotnet/attachments/20081019/6ee9ce7a/attachment-0001.html>


seasar-dotnet メーリングリストの案内