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 Listnodes = 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 Listcontexts = 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 DictionaryaryColumnData = 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; } } }