public override void CreateDatabase(ICodeDbConnection connection, string databaseName, string owner) { using (var cmd = connection.CreateCommand()) { var context = new ElementCode(); context.Add(SqlKeyword.CreateDatabase); context.Concat(Quote(databaseName)); context.Add(SqlKeyword.Owner); context.Concat(Quote(owner)); context.Go(); context.Build().Execute(cmd); } }
static void Drop(ElementCode context, string tableName, IUniqueDef unique) { if (unique == null) { return; } context.Add(SqlKeyword.AlterTable, SqlKeyword.IfExists); context.Concat(tableName); context.Add(SqlKeyword.DropConstraint, SqlKeyword.IfExists); context.Concat(unique.Name); context.Go(); }
static void Drop(ElementCode context, string tableName, IPrimaryKeyDef primaryKey) { if (primaryKey == null) { return; } context.Add(SqlKeyword.AlterTable, SqlKeyword.IfExists); context.Concat(tableName); context.Add(SqlKeyword.DropConstraint, SqlKeyword.IfExists); context.Concat(primaryKey.Name); context.Go(); }
static void Drop(ElementCode context, string tableName, IColumnDef column) { if (column == null) { return; } context.Add(SqlKeyword.AlterTable, SqlKeyword.IfExists); context.Concat(tableName); context.Add(SqlKeyword.DropColumn, SqlKeyword.IfExists); context.Concat(column.Name); context.Go(); }
public override void CreateRole(ICodeDbConnection connection, string roleName, string password) { using (var cmd = connection.CreateCommand()) { var context = new ElementCode(); context.Add(SqlKeyword.CreateRole); context.Concat(Quote(roleName)); context.Add(SqlKeyword.Password); context.Concat(string.Concat("'", password, "'")); context.Concat("LOGIN"); context.Go(); context.Build().Execute(cmd); } }
/// <summary> /// SQL文を生成する /// </summary> /// <param name="context">生成先のコンテキスト</param> public void ToElementCode(ElementCode context) { var delayedCode = new DelayedCodeGenerator((wb) => { var ec = new ElementCode(); ec.BeginParenthesize(); ec.Add(SqlKeyword.Values); var list = this.List; for (int i = 0, n = list.Count; i < n; i++) { if (i != 0) { ec.AddComma(); } ec.BeginParenthesize(); ec.AddValues <TColumns>(list[i]); ec.EndParenthesize(); } ec.EndParenthesize(); ec.Add(this); ec.BeginParenthesize(); ec.AddColumns(this.ColumnMap, column => ec.Concat(column.Name)); ec.EndParenthesize(); ec.Build(wb); }); context.Add(delayedCode); context.RegisterBuildHandler(this, (item, wb) => { // delayedCode 内でエイリアス名付与するので、既存の処理をオーバーライドし何もしないようにする }); }
static void Add(ElementCode context, string tableName, IColumnDef column, Action <IColumnDef> columnOption) { if (column == null) { return; } context.Add(SqlKeyword.AlterTable, SqlKeyword.IfExists); context.Concat(tableName); context.Add(SqlKeyword.AddColumn); context.Concat(column.Name); if (columnOption != null) { columnOption(column); } context.Go(); }
/// <summary> /// 同一値が存在しない場合のみ挿入するように判定を追加する /// </summary> /// <param name="columnCountToWhere">NOT EXISTS (SELECT * FROM t WHERE t.Name = "test") の部分で判定に使用する列数、0が指定されたら全て使用する</param> public void IfNotExists(int columnCountToWhere = 0) { var valueSetter = this.ValueNode as ValueSetter; if (valueSetter != null) { if (columnCountToWhere <= 0 || this.ColumnMap.Count < columnCountToWhere) { columnCountToWhere = this.ColumnMap.Count; } // WHERE NOT EXISTS部作成 var notExistsSelectFrom = new ElementCode(); var columnMap = this.ColumnMap; notExistsSelectFrom.Add(SqlKeyword.NotExists); notExistsSelectFrom.BeginParenthesize(); notExistsSelectFrom.Add(SqlKeyword.Select, SqlKeyword.Asterisk, SqlKeyword.From); notExistsSelectFrom.Add(this.Table); notExistsSelectFrom.Add(SqlKeyword.Where); for (int i = 0; i < columnCountToWhere; i++) { if (i != 0) { notExistsSelectFrom.Add(SqlKeyword.And); } notExistsSelectFrom.Add(columnMap[i]); notExistsSelectFrom.Concat("="); notExistsSelectFrom.Add(valueSetter.ColumnMap[i].Source); } notExistsSelectFrom.EndParenthesize(); valueSetter.Where(notExistsSelectFrom); } }
protected override Expression VisitBinary(BinaryExpression node) { var nodeType = node.NodeType; if (nodeType == ExpressionType.ArrayIndex) { _Code.Push(); this.Visit(node.Left); _Code.Pop(); _Code.Concat("["); this.Visit(Expression.Add(node.Right, Expression.Constant(1))); _Code.Concat("]"); } else { var l = node.Left; var r = node.Right; var p = GetOperatorPrecedence(nodeType); if (p == GetOperatorPrecedence(l.NodeType)) { this.Visit(l); } else { _Code.Push(); this.Visit(l); _Code.Pop(); } if (nodeType == ExpressionType.Equal && r.NodeType == ExpressionType.Constant && Evaluate(r) == null) { _Code.Add(SqlKeyword.IsNull); } else if (nodeType == ExpressionType.NotEqual && r.NodeType == ExpressionType.Constant && Evaluate(r) == null) { _Code.Add(SqlKeyword.IsNotNull); } else { _Code.Add(nodeType); if (p == GetOperatorPrecedence(r.NodeType)) { this.Visit(r); } else { _Code.Push(); this.Visit(r); _Code.Pop(); } } } return(node); }
static void Add(ElementCode context, string tableName, IIndexDef index) { if (index == null) { return; } context.Add(SqlKeyword.CreateIndex, SqlKeyword.IfNotExists); context.Concat(index.Name); context.Add(SqlKeyword.On); context.Concat(tableName); if ((index.Flags & IndexFlags.Gin) != 0) { context.Add(SqlKeyword.Using); context.Concat("gin"); } context.AddColumnDefs(index.Columns); context.Go(); }
static void Drop(ElementCode context, string tableName, IIndexDef index) { if (index == null) { return; } context.Add(SqlKeyword.DropIndex, SqlKeyword.IfExists); context.Concat(index.Name); context.Go(); }
/// <summary> /// SQL文を生成する /// </summary> /// <param name="context">生成先のコンテキスト</param> public void ToElementCode(ElementCode context) { int i = 0; context.Add(SqlKeyword.Select); context.AddColumns(this.ColumnMap, column => { context.Add(column.Source); context.Add(SqlKeyword.As); context.Concat("c" + (i++)); }); }
/// <summary> /// SQL文を生成する /// </summary> /// <param name="context">生成先のコンテキスト</param> public void ToElementCode(ElementCode context) { var environment = this.Table.Environment; context.Add(SqlKeyword.InsertInto); context.Concat(this.Table.Name); context.AddColumnDefs(this.ColumnMap); var valueNode = this.ValueNode; if (valueNode != null) { valueNode.ToElementCode(context); return; } throw new ApplicationException(); }
public void ToElementCode(ElementCode context) { // SELECT 部分作成 int i = 0; context.Add(SqlKeyword.Select); context.AddColumns(this.ColumnMap, column => { context.Add(column.Source); context.Add(SqlKeyword.As); context.Concat("c" + (i++)); }); // WHERE 部分作成 if (this.WhereNode != null) { this.WhereNode.ToElementCode(context); } }
/// <summary> /// SQL文を生成する /// </summary> /// <param name="context">生成先のコンテキスト</param> public void ToElementCode(ElementCode context) { if (this.FromNode == null) { throw new ApplicationException(); } // SELECT 部作成 int i = 0; context.Add(SqlKeyword.Select); context.AddColumns(this.ColumnMap, column => { context.Add(column.Source); context.Add(SqlKeyword.As); context.Concat("c" + (i++)); }); // FROM 部作成 this.FromNode.ToElementCode(context); }
static void Main(string[] args) { var E = TestDb.E; using (var con = E.CreateConnection("User ID=postgres;Password=wertyu89?;Host=localhost;Port=5432;Database=postgres;")) { con.Open(); try { E.CreateRole(con, RoleName, "Passw0rd!"); } catch (CodeDbEnvironmentException ex) { if (ex.ErrorType != DbEnvironmentErrorType.DuplicateObject) { throw; } } try { E.CreateDatabase(con, DbName, RoleName); } catch (CodeDbEnvironmentException ex) { if (ex.ErrorType != DbEnvironmentErrorType.DuplicateDatabase) { throw; } } } using (var con = E.CreateConnection($"User ID={RoleName};Password='******';Host=localhost;Port=5432;Database={DbName};")) { con.Open(); var cmd = con.CreateCommand(); cmd.CommandTimeout = 0; { var s = TestDb.E.NewSql(); s.DropTable(TestDb.User); s.Build().Execute(cmd); } // データベースの状態を取得 var current = E.ReadDatabaseDef(con); // クラスからデータベース定義を生成する var target = E.GenerateDatabaseDef(typeof(TestDb), "test_db"); // 差分を生成 var delta = E.GetDatabaseDelta(current, target); // 差分を適用する var context = new ElementCode(); E.ApplyDatabaseDelta(context, delta); context.Build().Execute(cmd); { var sql = TestDb.E.NewSql(); sql.InsertIntoWithValue(TestDb.User, t => new[] { t.UserName == "a" }); sql.InsertIntoWithValue(TestDb.User, t => new[] { t.UserName == "b" }); sql.InsertIntoWithValue(TestDb.User, t => new[] { t.UserName == "c" }); sql.BuildAction().Execute(cmd); } { var sql = TestDb.E.NewSql(); var select = sql.From(TestDb.User).Where(t => t.UserName == "a").Select(t => new { t.UserName, t.UserID, t.CreateDateTime }); var f = sql.BuildSelectFunc(select); using (var reader = f.Execute(cmd)) { foreach (var record in reader.Records) { Console.WriteLine($"{record.UserID} {record.UserName} {record.CreateDateTime}"); } } } { var code = new ElementCode(); var arg1 = new Argument(0); var arg2 = new Argument(0); code.Concat("SELECT ARRAY[1, 2, 3], '{8EA22A18-EB0A-49E5-B61D-F026CA7773FF}'::uuid, now(),"); code.Add(arg1); code.Go(); code.Concat("SELECT ARRAY[1, 2, 3], '{8EA22A18-EB0A-49E5-B61D-F026CA7773FF}'::uuid, now(),"); code.Add(arg2); code.Go(); var s = TestDb.E.NewSql(); s.Code(code); var commandable = s.BuildFunc <int, int, Tuple <int[], Guid, DateTime, int> >(arg1, arg2); using (var reader = commandable.Execute(cmd, 16, 32)) { do { foreach (var record in reader.Records) { Console.WriteLine(record); } } while (reader.DataReader.NextResult()); } } } }
/// <summary> /// SQL文を生成する /// </summary> /// <param name="context">生成先のコンテキスト</param> public void ToElementCode(ElementCode context) { context.Concat(this.Name); }
/// <summary> /// SQL文を生成する /// </summary> /// <param name="context">生成先のコンテキスト</param> public void ToElementCode(ElementCode context) { context.Add(SqlKeyword.DropTable, SqlKeyword.IfExists); context.Concat(this.Table.Name); }
public override void ApplyDatabaseDelta(ElementCode context, IDatabaseDelta databaseDelta) { // 列の型など付与するデリゲート Action <IColumnDef> columnOption = (column) => { context.Concat(column.DbType.ToDbTypeString((column.Flags & ColumnFlags.Serial) != 0 ? DbTypeStringFlags.Serial : 0)); if ((column.Flags & ColumnFlags.Nullable) != 0) { context.Add(SqlKeyword.Null); } else { context.Add(SqlKeyword.NotNull); } if ((column.Flags & ColumnFlags.DefaultCurrentTimestamp) != 0) { context.Add(SqlKeyword.Default, SqlKeyword.CurrentTimestamp); } }; // 捨てるべきテーブルを捨てる foreach (var table in databaseDelta.TablesToDrop) { context.Add(SqlKeyword.DropTable, SqlKeyword.IfExists); context.Concat(table.Name); context.Go(); } // 新たに増えるテーブルを作成する foreach (var table in databaseDelta.TablesToAdd) { var tableName = table.Name; // テーブル本体 context.Add(SqlKeyword.CreateTable, SqlKeyword.IfNotExists); context.Concat(tableName); context.AddColumnDefs(table.ColumnDefs, null, columnOption); context.Go(); // プライマリキー Add(context, tableName, table.GetPrimaryKey()); // インデックス foreach (var index in table.GetIndices()) { Add(context, tableName, index); } // ユニークキー foreach (var unique in table.GetUniques()) { Add(context, tableName, unique); } } // 変化するテーブルに対応する foreach (var table in databaseDelta.TablesToModify) { var tableName = table.Name; // 先にプライマリキー等の制約を捨てる Drop(context, tableName, table.PrimaryKeyToDrop); foreach (var index in table.IndicesToDrop) { Drop(context, tableName, index); } foreach (var unique in table.UniquesToDrop) { Drop(context, tableName, unique); } // 列を捨てる foreach (var column in table.ColumnsToDrop) { Drop(context, tableName, column); } // 列を追加する foreach (var column in table.ColumnsToAdd) { Add(context, tableName, column, columnOption); } // プライマリキー追加 Add(context, tableName, table.PrimaryKeyToAdd); // インデックス追加 foreach (var index in table.IndicesToAdd) { Add(context, tableName, index); } // ユニークキー追加 foreach (var unique in table.UniquesToAdd) { Add(context, tableName, unique); } } }