public SqlBuilder GetCountSql <TRecord>(IQuery aIQuery) where TRecord : class, IRecord, new() { //aQueryのDownキャスト Query <TRecord> aQuery = (Query <TRecord>)aIQuery; //TRecord型レコードとViewのマッピング情報を取得する RecordViewTableMap <TRecord> aRecordViewMap = _aRecordViewTableMapFactory.CreateRecordViewTableMap <TRecord>(); //TRecordに対応するSqlPodを生成する SqlPod aSqlPod = _aSqlPodFactory.CreateSqlPod <TRecord>(); //aQueryが持つ条件のプロパティ型リテラル値をDBデータ型に型変換する aQuery = aRecordViewMap.CastQuery(aQuery); //SQL文を作成する RecordViewTableMap <TRecord> aRecordViewTableMap = _aRecordViewTableMapFactory.CreateRecordViewTableMap <TRecord>(); return(aSqlPod.GetCountSql(aQuery, aRecordViewTableMap)); }
public RecordViewTableMap <TRecord> CreateRecordViewTableMap <TRecord>() where TRecord : class, IRecord, new() { var recordName = RecordInfo <TRecord> .GetInstance().Name; // _mapHashへのデータ有無の判断と書込み読込みを不可分処理とする if (!_mapHash.ContainsKey(recordName)) { lock (_mapHash) { if (!_mapHash.ContainsKey(recordName)) { var newMap = new RecordViewTableMap <TRecord>(_aDb); _mapHash.Add(recordName, newMap); } } } return((RecordViewTableMap <TRecord>)_mapHash[recordName]); }
internal SqlBuilder GetCountSql <TRecord>(Query <TRecord> aQuery , RecordViewTableMap <TRecord> aRecordViewTableMap = null) where TRecord : class, IRecord, new() { //サブクラスでSqlPod.CountSql()にSQLが定義されていなければ、 //SELECT文にSELECT COUNT(*)を付加する if (this.CountSql() == null) { SqlBuilder selectSql = this.GetSelectSql(aQuery, aRecordViewTableMap); selectSql.ClearOrderBy(); //Return "SELECT COUNT(*) FROM (" + selectSql + ") V1_" selectSql.SetCount(); return(selectSql); } SqlBuilder sql = this.CountSql(); //Query.RowRange()で抽出条件が指定されている場合 if (aQuery.GetRowRange() != null & aRecordViewTableMap != null) { int begin = aQuery.GetRowRange().Item1; int end = aQuery.GetRowRange().Item2; sql.SetRowLimit(begin, end); } //Pervasiveを除くDBMSではWHERE句などにAS別名は使用できない sql.WrapInSelectStar(aRecordViewTableMap.GetAllColumns(sql)); //最大抽出件数の設定 //OracleのRowNumによる指定は、SELECT * FROMに指定する if (aQuery.GetMaxRows() >= 0) { sql.SetMaxRows(aQuery.GetMaxRows()); } //AND条件の追加 if (sql.GetAutoWhere()) { sql.AddAndPredicate(aQuery.GetWhereExp()); } return(sql); }
public SqlBuilder GetSelectSql <TRecord>(Query <TRecord> query , LoadMode aLoadMode) where TRecord : class, IRecord, new() { //TRecord型レコードとViewのマッピング情報を取得する RecordViewTableMap <TRecord> aRecordViewMap = _aRecordViewTableMapFactory.CreateRecordViewTableMap <TRecord>(); //TRecordに対応するSqlPodを生成する SqlPod aSqlPod = _aSqlPodFactory.CreateSqlPod <TRecord>(); //aQueryが持つ条件のプロパティ型リテラル値をDBデータ型に型変換する query = aRecordViewMap.CastQuery(query); //SQL文を作成する //引数aLoadModeとaRecordTableMapを追加したのは苦渋の決断 //(SqlBuilderがテーブルのメタ情報を扱うことを想定していなかったので、後付による拡張が綺麗にならない) RecordViewTableMap <TRecord> aRecordViewTableMap = _aRecordViewTableMapFactory.CreateRecordViewTableMap <TRecord>(); return(aSqlPod.GetSelectSql(query, aRecordViewTableMap)); }
private LockData CreateLockDataSub <TRecord>(RecordViewTableMap <TRecord> aRecordViewTableMap , long apTranId , string recordName , string tableName , Dictionary <string, string> cnf) where TRecord : class, IRecord, new() { //主キーを含む全ての一致条件を格納するオブジェクト CNFofEquation cnfOfEquation = new CNFofEquation(); //主キーに対する一致条件のみを格納するオブジェクト CNFofEquation cnfOfPKey = new CNFofEquation(); //乗法標準形を用意する foreach (KeyValuePair <string, string> eqPredicate in cnf) { string varName = eqPredicate.Key; //SQLリテラル表記で値を取得する string value = eqPredicate.Value; //valueがIsNullPropertyValue()でNULL値と判定された場合、Predicateに含まれない(暫定実装) TableInfo aTableInfo = aRecordViewTableMap.GetTableInfo(tableName); ColumnInfo aColumnInfo = aTableInfo[varName]; //一致条件を述語に追加する cnfOfEquation.Add(new Equation(varName, value)); //主キーに対する一致条件であればcnfOfPKeyにも格納する if (aColumnInfo.PrimaryKey.HasValue && aColumnInfo.PrimaryKey.Value) { cnfOfPKey.Add(new Equation(varName, value)); //テーブルの全ての主キーに対する一致条件が取得できれば、 //主キーに対する一致条件のみの述語だけで必要十分である if (cnfOfPKey.Count == aTableInfo.GetPrimaryKeys().Count) { return(new LockData(apTranId, recordName, "", tableName, cnfOfPKey)); } } } return(new LockData(apTranId, recordName, "", tableName, cnfOfEquation)); }
/// <summary> /// SQL文の抽出条件からロックを作成する /// </summary> /// <typeparam name="TRecord"></typeparam> /// <param name="apTranId">APトランザクションID</param> /// <param name="sql">SQL文</param> /// <returns>作成したロックデータ</returns> /// <remarks></remarks> private List <LockData> CreateLockData <TRecord>(long apTranId , SqlBuilder sql) where TRecord : class, IRecord, new() { List <LockData> ret = new List <LockData>(); //TRecord型レコードとテーブルのマッピング情報を取得する RecordViewTableMap <TRecord> aRecordViewTableMap = _aRecordViewTableMapFactory.CreateRecordViewTableMap <TRecord>(); //TRecord型レコードのメタ情報を取得する RecordInfo <TRecord> aRecordInfo = aRecordViewTableMap.GetRecordInfo(); //テーブル列リストを作成する Dictionary <string, IEnumerable <string> > tableColumns = new Dictionary <string, IEnumerable <string> >(); foreach (string srcTableName in sql.GetSrcTableNames()) { //相関テーブルの主キーリストを作成する List <string> allColumnNames = new List <string>(); foreach (ColumnInfo column in aRecordViewTableMap.GetTableInfo(srcTableName).GetAllColumns()) { allColumnNames.Add(column.ColumnName); } tableColumns.Add(srcTableName, allColumnNames); } //SQL文の抽出条件からロック情報を作成する foreach (KeyValuePair <SqlTable, Dictionary <string, string> > tableNameCnfPair in sql.GetCNF(tableColumns)) { string srcTableName = tableNameCnfPair.Key.Name; Dictionary <string, string> cnf = tableNameCnfPair.Value; LockData aLockData = this.CreateLockDataSub(aRecordViewTableMap , apTranId , aRecordInfo.Name , srcTableName , cnf); ret.Add(aLockData); } return(ret); }
private List <LockData> CreateLockDataFromRecord_new <TRecord>(long apTranId , TRecord aRecord , IEnumerable <SqlTable> usedTableNames) where TRecord : class, IRecord, new() { List <LockData> ret = new List <LockData>(); //TRecord型レコードとテーブルのマッピング情報を取得する RecordViewTableMap <TRecord> aRecordViewTableMap = _aRecordViewTableMapFactory.CreateRecordViewTableMap <TRecord>(); //TRecord型レコードのメタ情報を取得する RecordInfo <TRecord> aRecordInfo = aRecordViewTableMap.GetRecordInfo(); foreach (KeyValuePair <SqlTable, Dictionary <string, SqlExpr> > kv in aRecordViewTableMap.GetCNFExpression(aRecord , usedTableNames)) { string tableName = kv.Key.Name; //CNFを作成する Dictionary <string, string> cnf = new Dictionary <string, string>(); foreach (KeyValuePair <string, SqlExpr> eq in kv.Value) { //CNFの素論理式はリテラル値への一致条件のみとする if (eq.Value.IsLiteral) { cnf.Add(eq.Key, eq.Value.ToString()); } } //ロック情報を作成する LockData aLockData = this.CreateLockDataSub(aRecordViewTableMap , apTranId , aRecordInfo.Name , tableName , cnf); ret.Add(aLockData); } return(ret); }
/// <summary> /// SELECT文を取得する /// </summary> /// <param name="aQuery">最大抽出件数,AND条件,OrderBy句,プレースホルダ値をQueryオブジェクトで指定する</param> /// <returns></returns> /// <remarks>PervasiveはWhere句などにAS別名が使用できるので、 /// SelectSql()で生成したSQLを抱合するSELECT文は必要ない。(Oracleでは必要)</remarks> internal SqlBuilder GetSelectSql <TRecord>(Query <TRecord> aQuery , RecordViewTableMap <TRecord> aRecordViewTableMap) where TRecord : class, IRecord, new() { SqlBuilder sql = this.SelectSql(); // OrderBy句の追加 // (WrapInSelectStar()でOrderBy句の変換処理を行うのでWrapInSelectStar()の前に処理する) sql.AddOrderBy(aQuery.GetOrderByExp()); // AS別名とテーブル列名が重複する場合にSQL実行エラーになることがあるため // 全てのSELECT文についてSELECT * で囲む sql.WrapInSelectStar(aRecordViewTableMap.GetAllColumns(sql)); //最大抽出件数の設定 //OracleのRowNumによる指定は、SELECT * FROMに指定する if (aQuery.GetMaxRows() >= 0) { sql.SetMaxRows(aQuery.GetMaxRows()); } if (sql.GetAutoWhere()) { //AND条件の追加 sql.AddAndPredicate(aQuery.GetWhereExp()); } //Query.RowRange()で抽出条件が指定されている場合 if (aQuery.GetRowRange() != null) { int begin = aQuery.GetRowRange().Item1; int end = aQuery.GetRowRange().Item2; sql.SetRowLimit(begin, end); } return(sql); }