MySQL用ダミーデータ作成ツール MyDummySQL ve0.1 を作ってみた

ちらほらと作っていたMyDummySQL、ver0.1になりました。 
すみません。ver0.1にはMySQLのライブラリが入っていませんでした。そのため動作しませんでした。
今はMySQLライブラリを追加したver0.2を下記URLに置いています。
ve0.2は開発PCとは別PC(XPMode)で、動作確認しています。
どうもすみませんでした。m(_’_)m 以後気をつけます。

下記URLからダウンロードできます。
http://la-bit.sakura.ne.jp/download/mydummysql/

XPModeでの実行の様子。(テーブルに10,000行Insert)

そのうちマニュアル作ります。
あ、日付型、日時型には対応していません。そのうち対応します。

ダミーデータ生成ロジックは以下のUMLの様です。

UMLで作ったら、なんだか1つのクラスに1つの責務のみを与えられるようになり、クラスが単純化した。
実装後のデバックでもバグが少ないような。


main.mdbにID列(数値型)とval列(文字列型)のテーブル作ると、MyDummySQLで読み込めます。
人名辞書とか地名辞書とか登録しておくと良いです。

Context.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyDummySQL.FactoryNS;
using MyDummySQL.NodeNS;

namespace MyDummySQL.ContextNS
{
    abstract class Context
    {
        protected string param = "";
        protected INode node = null;
        public int no { get; set; }

        public Context(string param_, int no_)
        {
            this.param = param_;
            this.no = no_;


            /*
            ProgramNodefactory fac = new ProgramNodefactory();
            this.node = fac.Create(this);
             */
        }

        public string NextString()
        {
            return this.node.NextString();
        }
    }
}

SeqNumberContext.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyDummySQL.FactoryNS;

namespace MyDummySQL.ContextNS
{
    class SeqNumberContext : Context
    {
        public long StartInt = 0;
        public long EndInt = 0;

        public SeqNumberContext(string param_, int no_)
            : base(param_,no_)
        {
            this.Parse();

            ProgramNodefactory fac = new ProgramNodefactory();
            this.node = fac.Create(this);
        }

        private void Parse()
        {
            char sep = { ',' };
            string p = this.param.Split(sep);

            if (p.Length < 2)
            {
                throw new ArgumentException("順序番号コマンドの引数は2つ指定して下さい。");
            }

            long.TryParse(p[0], out this.StartInt);
            long.TryParse(p[1], out this.EndInt);
        }

    }
}

SeqAccessTableContext.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyDummySQL.FactoryNS;

namespace MyDummySQL.ContextNS
{
    class SeqAccessTableContext : Context
    {
        public string TableName;

        public SeqAccessTableContext(string param_, int no_)
            : base(param_,no_)
        {
            this.Parse();

            ProgramNodefactory fac = new ProgramNodefactory();
            this.node = fac.Create(this);
        }

        private void Parse()
        {
            this.TableName = this.param;
        }
    }
}

列ダミーデータジェネレーターはINodeで。

INode.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyDummySQL.NodeNS
{
    interface INode
    {
        //long NextInt();
        string NextString();
    }
}

INodeの実装例

SeqNumberNode.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyDummySQL.NodeNS
{
    class SeqNumberNode : INode
    {
        private long startInt = 0;
        private long endInt = 0;
        private long currentInt = 0;
        public SeqNumberNode(long startInt_, long endInt_)
        {
            //ガード
            if (startInt_ >= endInt_)
            {
                ArgumentException aexcep = new ArgumentException("startIntがendIntより大きな数です。");
                throw aexcep;
            }

            this.startInt = startInt_;
            this.endInt = endInt_;

            this.currentInt = this.startInt - 1;
        }
        public string NextString()
        {
            //インクリメント
            this.currentInt++;
            
            //フィルター、リミッター
            if (this.currentInt <= this.startInt)
            {
                this.currentInt = this.startInt;
            }
            if (this.currentInt > this.endInt)
            {
                this.currentInt = this.startInt;
            }

            //戻り値
            return this.currentInt.ToString();
        }

    }
}

INodeの実装例2(Accessテーブル読み込み)

SeqAccessTableNode.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using MyDummySQL.DAOs;

namespace MyDummySQL.NodeNS
{
    class SeqAccessTableNode : INode
    {
        private DataTable table = null;
        private int no = 0;

        public SeqAccessTableNode(string tableName)
        {
            using (DAOContext con = new DAOContext(AccessConstring.conString))
            {
                con.OpenConnection();

                tableDAO dao = new tableDAO(con, tableName);
                this.table = dao.selectAll();

                con.CloseConnection();
            }
        }

        public string NextString()
        {
            string ret = this.table.Rows[this.no]["val"].ToString();
            this.no++;
            if (this.no >= this.table.Rows.Count)
            {
                this.no = 0;
            }

            return ret;
        }
    }
}

Contextのファクトリ
ContextFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyDummySQL.ContextNS;

namespace MyDummySQL.FactoryNS
{
    class ContextFactory
    {

        public ContextFactory()
        {
        }

        public Context Create(string atomParam, int no)
        {
            char sep = { ':' };
            string parts = atomParam.Split(sep);

            //ガード
            if (parts.Length != 2)
            {
                throw new ArgumentException("アトムコマンドのフォーマットエラーです。「:」で区切ってください。");
            }

            switch (parts[0].ToLower())
            {
                case "seqint":
                    return new SeqNumberContext(parts[1], no);
                    //break;
                case "rndint":
                    return new RandomNumberContext(parts[1], no);
                    //break;
                case "seqactbl":
                    return new SeqAccessTableContext(parts[1], no);
                case "rndactbl":
                    return new RandomAccessTableContext(parts[1], no);
                case "seqmstbl":
                    return new SeqMySQLTableContext(parts[1], no);
                case "rndmstbl":
                    return new RandomMySQLTableContext(parts[1], no);
                case "const":
                    return new ConstStringContext(parts[1], no);
                default:
                    throw new ArgumentException("存在しないアトムコマンドです。");
            }
        }
    }
}

INodeのファクトリ
ProgramNodeFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyDummySQL.ContextNS;
using MyDummySQL.NodeNS;

namespace MyDummySQL.FactoryNS
{
    class ProgramNodefactory
    {
        private List nodes = new List();

        public ProgramNodefactory()
        {
        }

        /*
         * 基底クラスを引数にしない
        public void Visit(Context cxt)
        {
        }
         */
        public INode Create(Context cxt)
        {
            NotImplementedException excep = new NotImplementedException("このメソッドの引数クラスは抽象クラスです。");
            throw excep;
            //return null;
        }
        public INode Create(SeqNumberContext seqCtx)
        {
            return new SeqNumberNode(seqCtx.StartInt, seqCtx.EndInt);
        }

        public INode Create(RandomNumberContext rndCxt)
        {
            return new RandomNumberNode(rndCxt.StartInt, rndCxt.EndInt);
        }

        public INode Create(SeqAccessTableContext seqAcTblCxt)
        {
            return new SeqAccessTableNode(seqAcTblCxt.TableName);
        }

        public INode Create(RandomAccessTableContext rndAcTblCxt)
        {
            return new RandomAccessTableNode(rndAcTblCxt.TableName);
        }

        public INode Create(SeqMySQLTableContext seqMsTblCxt)
        {
            return new SeqMySQLTableNode(seqMsTblCxt.TableName, seqMsTblCxt.ColName);
        }

        public INode Create(RandomMySQLTableContext rndMsTblCxt)
        {
            return new RandomMySQLTableNode(rndMsTblCxt.TableName, rndMsTblCxt.ColName);
        }

        public INode Create(ConstStringContext cstStrgCxt)
        {
            return new ConstStringNode(cstStrgCxt.ConstString);
        }
    }
}

列のダミーデータの生成をINodeに委譲し使う側。
ColumnDataGenerator.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyDummySQL.ContextNS;
using MyDummySQL.FactoryNS;

namespace MyDummySQL.GeneratorNS
{
    class ColumnDataGenerator
    {
        private List contexts = new List();
        private string columnName = "";
        public ColumnDataGenerator(string columnName_, string param_)
        {
            this.columnName = columnName_;
            this.contexts = this.ParseParam(param_);
        }
        private List ParseParam(string param)
        {
            char sep = { '|' };
            string atoms = param.Split(sep);
            int no = 0;
            List cxts = new List();
            ContextFactory fac = new ContextFactory();

            no = 1;
            foreach (string atom in atoms)
            {
                if (string.IsNullOrEmpty(atom)) { continue; }
                Context cxt = fac.Create(atom,no);
                no++;

                cxts.Add(cxt);
            }

            return cxts;
        }

        public string BuildColumnData()
        {
            string ret = "";
            foreach (Context cxt in this.contexts)
            {
                ret += cxt.NextString().ToString();
            }

            return ret;
        }
    }
}

列名と列ダミーデータの対応を取るクラス。
ColumnData.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyDummySQL.GeneratorNS;

namespace MyDummySQL.Columns
{
    class ColumnData
    {
        //[ColumnName, Generator]の組
        private Dictionary aryColumnData = new Dictionary();
        //[ColumnName, Param]の組
        private Dictionary paramsByColumn = new Dictionary();

        public ColumnData(Dictionary paramsByColumn_)
        {
            this.paramsByColumn = paramsByColumn_;
            foreach (var key in this.paramsByColumn.Keys)
            {
                this.aryColumnData.Add(key, new ColumnDataGenerator(key,this.paramsByColumn[key]));
            }
        }

        //[ColumnName, 生成したColumnValue]の組
        public Dictionary GenerateNext()
        {
            Dictionary generatedValuesByColumn = new Dictionary();

            foreach (var key in this.aryColumnData.Keys)
            {
                ColumnDataGenerator g = this.aryColumnData[key];
                string columnName = key;
                string columnValue = g.BuildColumnData();

                generatedValuesByColumn.Add(columnName, columnValue);
            }

            return generatedValuesByColumn;
        }
    }
}