예제 #1
0
        private TableQuery <T> AddOrderBy <U>(Expression <Func <T, U> > orderExpr, bool asc)
        {
            if (orderExpr.NodeType != ExpressionType.Lambda)
            {
                throw new NotSupportedException("Must be a predicate");
            }

            var lambda = (LambdaExpression)orderExpr;
            var mem    = lambda.Body as MemberExpression;

            if (mem == null || (mem.Expression.NodeType != ExpressionType.Parameter))
            {
                throw new NotSupportedException("Order By does not support: " + orderExpr);
            }

            TableQuery <T> q = Clone();

            if (q._orderBys == null)
            {
                q._orderBys = new List <Ordering>();
            }
            q._orderBys.Add(new Ordering
            {
                ColumnName = OrmHelper.GetColumnName(mem.Member),
                Ascending  = asc
            });
            return(q);
        }
예제 #2
0
        public TableMapping(Type type)
        {
            this.MappedType = type;

            this.TableName            = OrmHelper.GetTableName(this.MappedType);
            this.OldTableName         = OrmHelper.GetOldTableName(this.MappedType);
            this.OnPrimaryKeyConflict = OrmHelper.GetOnPrimaryKeyConflict(this.MappedType);
            this._properties          = OrmHelper.GetProperties(this.MappedType);
            this.Columns     = this._properties.Select(x => new Column(x)).ToList();
            this.Checks      = OrmHelper.GetChecks(this.MappedType);
            this.ForeignKeys = OrmHelper.GetForeignKeys(this._properties);
            this.Indexes     = OrmHelper.GetIndexes(this.MappedType, this._properties);

            this.Virtual   = OrmHelper.GetVirtual(this.MappedType);
            this.Tokenizer = OrmHelper.GetTokenizer(this.MappedType);
        }
예제 #3
0
        public TableMapping(Type type)
        {
            MappedType = type;

            TableName            = OrmHelper.GetTableName(MappedType);
            OldTableName         = OrmHelper.GetOldTableName(MappedType);
            OnPrimaryKeyConflict = OrmHelper.GetOnPrimaryKeyConflict(MappedType);
            _properties          = OrmHelper.GetProperties(this.MappedType);
            Columns     = _properties.Select(x => new Column(x)).ToList();
            Checks      = OrmHelper.GetChecks(this.MappedType);
            ForeignKeys = OrmHelper.GetForeignKeys(_properties);
            Indexes     = OrmHelper.GetIndexes(MappedType, _properties);

            Virtual   = OrmHelper.GetVirtual(MappedType);
            Tokenizer = OrmHelper.GetTokenizer(MappedType);
        }
예제 #4
0
        private TableQuery <T> AddWith(params Expression <Func <T, object> >[] expressions)
        {
            TableQuery <T> q = Clone();

            if (q._withColumns == null)
            {
                q._withColumns = new List <WithColumn>();
            }
            foreach (var expression in expressions)
            {
                var member = GetMember(expression);
                q._withColumns.Add(new WithColumn {
                    ColumnName = OrmHelper.GetColumnName(member), Member = member
                });
            }
            return(q);
        }
예제 #5
0
        public static string GetCreateSql(this TableMapping.ForeignKey foreignKey)
        {
            var sb = new StringBuilder();

            if (!foreignKey.Name.IsNullOrWhitespace())
            {
                sb.Append("CONSTRAINT ");
                sb.Append(Quote(foreignKey.Name));
                sb.AppendLine();
            }
            sb.Append("FOREIGN KEY (");
            sb.Append(string.Join(", ", foreignKey.Keys.Keys.Select(Quote).ToArray()));
            sb.Append(")");
            sb.AppendLine();
            sb.Append("REFERENCES ");
            sb.Append(Quote(foreignKey.ChildTable));
            sb.Append(" (");
            sb.Append(string.Join(", ", foreignKey.Keys.Values.Select(Quote).ToArray()));
            sb.Append(")");
            if (foreignKey.OnUpdate != ForeignKeyAction.Default)
            {
                sb.AppendLine();
                sb.Append("ON UPDATE ");
                sb.Append(OrmHelper.GetForeignKeyActionString(foreignKey.OnUpdate));
            }
            if (foreignKey.OnDelete != ForeignKeyAction.Default)
            {
                sb.AppendLine();
                sb.Append("ON DELETE ");
                sb.Append(OrmHelper.GetForeignKeyActionString(foreignKey.OnDelete));
            }
            if (foreignKey.NullMatch != NullMatch.Default)
            {
                sb.AppendLine();
                sb.Append("MATCH ");
                sb.Append(foreignKey.NullMatch);
            }
            if (foreignKey.Deferred != Deferred.Default)
            {
                sb.AppendLine();
                sb.Append("DEFERRABLE INITIALLY ");
                sb.Append(foreignKey.Deferred);
            }
            return(sb.ToString());
        }
예제 #6
0
            internal Column(PropertyInfo prop)
            {
                _prop = prop;
                this._dataConverter = null;

                Name = OrmHelper.GetColumnName(prop);
                // If this type is Nullable<T> then Nullable.GetUnderlyingType returns the T,
                // otherwise it returns null, so get the the actual type instead
                ColumnType                  = OrmHelper.GetColumnType(prop);
                Collation                   = OrmHelper.GetCollation(prop);
                PrimaryKey                  = OrmHelper.GetPrimaryKey(prop);
                IsNullable                  = this.PrimaryKey == null && OrmHelper.GetIsColumnNullable(prop);
                IsAutoIncrement             = OrmHelper.GetIsAutoIncrement(prop);
                Unique                      = OrmHelper.GetUnique(prop);
                MaxStringLength             = OrmHelper.GetMaxStringLength(prop);
                Checks                      = OrmHelper.GetChecks(prop);
                DefaultValue                = OrmHelper.GetDefaultValue(prop);
                this.DataConverterAttribute = OrmHelper.GetDataConverter(prop);
            }
예제 #7
0
        private CompileResult CompileExpr(Expression expr, List <object> queryArgs)
        {
            if (expr == null)
            {
                throw new NotSupportedException("Expression is NULL");
            }

            if (expr is BinaryExpression)
            {
                var bin = (BinaryExpression)expr;

                CompileResult leftr  = CompileExpr(bin.Left, queryArgs);
                CompileResult rightr = CompileExpr(bin.Right, queryArgs);

                //If either side is a parameter and is null, then handle the other side specially (for "is null"/"is not null")
                string text;
                if (leftr.CommandText == "?" && leftr.Value == null)
                {
                    text = CompileNullBinaryExpression(bin, rightr);
                }
                else if (rightr.CommandText == "?" && rightr.Value == null)
                {
                    text = CompileNullBinaryExpression(bin, leftr);
                }
                else
                {
                    text = "(" + leftr.CommandText + " " + GetSqlName(bin) + " " + rightr.CommandText + ")";
                }
                return(new CompileResult {
                    CommandText = text
                });
            }
            else if (expr.NodeType == ExpressionType.Call)
            {
                var call = (MethodCallExpression)expr;
                var args = new CompileResult[call.Arguments.Count];
                var obj  = call.Object != null?CompileExpr(call.Object, queryArgs) : null;

                string methodName = call.Method.Name;
                string sqlCall    = string.Empty;

                for (int i = 0; i < args.Length; i++)
                {
                    args[i] = CompileExpr(call.Arguments[i], queryArgs);
                }

                if (methodName == "Contains")
                {
                    if (args.Length == 1)
                    {
                        // string.Contains("xxx") or list.Contains(x)
                        if (call.Object != null && call.Object.Type == typeof(string))
                        {
                            sqlCall = "({0} like ('%' || {1} || '%'))";
                        }
                        else
                        {
                            sqlCall = "({1} in {0})";
                        }

                        sqlCall = string.Format(sqlCall, obj.CommandText, args[0].CommandText);
                    }
                    else if (args.Length == 2)
                    {
                        sqlCall = string.Format("({0} in {1})", args[1].CommandText, args[0].CommandText);
                    }
                }
                else if (methodName == "StartsWith" || methodName == "EndsWith")
                {
                    if (args.Length == 1)
                    {
                        if (methodName == "StartsWith")
                        {
                            sqlCall = "({0} like ({1} || '%'))";
                        }
                        else if (methodName == "EndsWith")
                        {
                            sqlCall = "({0} like ('%' || {1}))";
                        }

                        sqlCall = string.Format(sqlCall, obj.CommandText, args[0].CommandText);
                    }
                }
                else if (methodName == "Matches" && args.Length == 2)
                {
                    sqlCall = "({0} match {1})";
                    sqlCall = string.Format(sqlCall, args[0].CommandText, args[1].CommandText);
                }
                else
                {
                    var arguments = string.Join(",", args.Select(a => a.CommandText).ToArray());
                    sqlCall = string.Format("{0}({1})", methodName.ToLower(), arguments);
                }

                return(new CompileResult {
                    CommandText = sqlCall
                });
            }
            else if (expr.NodeType == ExpressionType.Constant)
            {
                var c = (ConstantExpression)expr;
                queryArgs.Add(c.Value);
                return(new CompileResult
                {
                    CommandText = "?",
                    Value = c.Value
                });
            }
            else if (expr.NodeType == ExpressionType.Convert)
            {
                var           u    = (UnaryExpression)expr;
                Type          ty   = u.Type;
                CompileResult valr = CompileExpr(u.Operand, queryArgs);

                var underlyingType = Nullable.GetUnderlyingType(ty);
                if (underlyingType != null)
                {
                    ty = underlyingType;
                }

                return(new CompileResult
                {
                    CommandText = valr.CommandText,
                    Value = valr.Value != null?Convert.ChangeType(valr.Value, ty, null) : null
                });
            }
            else if (expr.NodeType == ExpressionType.MemberAccess)
            {
                var mem = (MemberExpression)expr;

                if (mem.Expression.NodeType == ExpressionType.Parameter)
                {
                    //
                    // This is a column of our table, output just the column name
                    //
                    return(new CompileResult {
                        CommandText = "\"" + OrmHelper.GetColumnName(mem.Member) + "\""
                    });
                }
                else
                {
                    object obj = null;
                    if (mem.Expression != null)
                    {
                        CompileResult r = CompileExpr(mem.Expression, queryArgs);
                        if (r.Value == null)
                        {
                            throw new NotSupportedException("Member access failed to compile expression");
                        }
                        if (r.CommandText == "?")
                        {
                            queryArgs.RemoveAt(queryArgs.Count - 1);
                        }
                        obj = r.Value;
                    }

                    //
                    // Get the member value
                    //
                    object val = null;

                    if (mem.Member is PropertyInfo)
                    {
                        var m = (PropertyInfo)mem.Member;
                        val = m.GetValue(obj, null);
                    }
                    else if (mem.Member is FieldInfo)
                    {
#if SILVERLIGHT
                        val = Expression.Lambda(expr).Compile().DynamicInvoke();
#else
                        var m = (FieldInfo)mem.Member;
                        val = m.GetValue(obj);
#endif
                    }
                    else
                    {
                        throw new NotSupportedException("MemberExpr: " + mem.Member.GetType().Name);
                    }

                    //
                    // Work special magic for enumerables
                    //
                    if (val != null && val is IEnumerable && !(val is string))
                    {
                        var sb = new StringBuilder();
                        sb.Append("(");
                        string head = "";
                        foreach (object a in (IEnumerable)val)
                        {
                            queryArgs.Add(a);
                            sb.Append(head);
                            sb.Append("?");
                            head = ",";
                        }
                        sb.Append(")");
                        return(new CompileResult
                        {
                            CommandText = sb.ToString(),
                            Value = val
                        });
                    }
                    else
                    {
                        queryArgs.Add(val);
                        return(new CompileResult
                        {
                            CommandText = "?",
                            Value = val
                        });
                    }
                }
            }
            throw new NotSupportedException("Cannot compile: " + expr.NodeType.ToString());
        }
예제 #8
0
            public string GetCreateSql(TableMapping table)
            {
                var constraints = new List <string>();

                if (this.PrimaryKey != null && table.PrimaryKey.Columns.Length == 1)
                {
                    constraints.Add(string.Format(CultureInfo.InvariantCulture, "{0} PRIMARY KEY {1}",
                                                  string.IsNullOrEmpty(this.PrimaryKey.Name)
                                                      ? string.Empty
                                                      : string.Format(CultureInfo.InvariantCulture, "CONSTRAINT {0}", this.PrimaryKey.Name),
                                                  this.PrimaryKey.Direction));
                    if (table.OnPrimaryKeyConflict != ConflictResolution.Default)
                    {
                        constraints.Add(string.Format(CultureInfo.InvariantCulture, "ON CONFLICT {0}", table.OnPrimaryKeyConflict));
                    }
                    if (table.AutoIncrementColumn == this)
                    {
                        constraints.Add("AUTOINCREMENT");
                    }
                }

                if (this.Unique != null)
                {
                    constraints.Add(string.Format(CultureInfo.InvariantCulture, "UNIQUE {0}",
                                                  this.Unique.OnConflict != ConflictResolution.Default
                                                      ? string.Format(CultureInfo.InvariantCulture, "ON CONFLICT {0}", this.Unique.OnConflict)
                                                      : string.Empty));
                }
                if (!this.IsNullable)
                {
                    constraints.Add("NOT NULL");
                }
                if (this.Checks.Any())
                {
                    constraints.Add(string.Join(" ", this.Checks.Select(c => string.Format(CultureInfo.InvariantCulture, "CHECK ({0})", c)).ToArray()));
                }
                if (!string.IsNullOrEmpty(this.DefaultValue))
                {
                    constraints.Add(string.Format(CultureInfo.InvariantCulture, "DEFAULT({0})", this.DefaultValue));
                }
                if (this.Collation != Collation.Default)
                {
                    constraints.Add(string.Format(CultureInfo.InvariantCulture, "COLLATE {0}", this.Collation));
                }

                return(string.Format(CultureInfo.InvariantCulture, "[{0}] {1} {2}", this.Name, OrmHelper.SqlType(this), string.Join(" ", constraints.ToArray())));
            }