예제 #1
0
 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);
     }
 }
예제 #2
0
 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();
 }
예제 #3
0
 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();
 }
예제 #4
0
 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();
 }
예제 #5
0
 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);
     }
 }
예제 #6
0
파일: Values.cs 프로젝트: nQuantums/tips
        /// <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 内でエイリアス名付与するので、既存の処理をオーバーライドし何もしないようにする
            });
        }
예제 #7
0
 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();
 }
예제 #8
0
        /// <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);
            }
        }
예제 #9
0
        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);
        }
예제 #10
0
 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();
 }
예제 #11
0
 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();
 }
예제 #12
0
        /// <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++));
            });
        }
예제 #13
0
        /// <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();
        }
예제 #14
0
        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);
            }
        }
예제 #15
0
        /// <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);
        }
예제 #16
0
파일: Program.cs 프로젝트: nQuantums/tips
        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());
                    }
                }
            }
        }
예제 #17
0
파일: TableDef.cs 프로젝트: nQuantums/tips
 /// <summary>
 /// SQL文を生成する
 /// </summary>
 /// <param name="context">生成先のコンテキスト</param>
 public void ToElementCode(ElementCode context)
 {
     context.Concat(this.Name);
 }
예제 #18
0
파일: DropTable.cs 프로젝트: nQuantums/tips
 /// <summary>
 /// SQL文を生成する
 /// </summary>
 /// <param name="context">生成先のコンテキスト</param>
 public void ToElementCode(ElementCode context)
 {
     context.Add(SqlKeyword.DropTable, SqlKeyword.IfExists);
     context.Concat(this.Table.Name);
 }
예제 #19
0
        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);
                }
            }
        }