Ejemplo n.º 1
0
        public UpsertFunction(IDocumentMapping mapping)
        {
            FunctionName = mapping.UpsertName;
            TableName    = mapping.TableName;

            var idType = mapping.IdMember.GetMemberType();

            PgIdType        = TypeMappings.GetPgType(idType);
            Id_NpgsqlDbType = TypeMappings.ToDbType(idType);

            Arguments.Add(new UpsertArgument
            {
                Arg          = "docId",
                PostgresType = PgIdType,
                Column       = "id",
                Members      = new[] { mapping.IdMember }
            });
            Arguments.Add(new UpsertArgument
            {
                Arg                = "doc",
                PostgresType       = "JSONB",
                DbType             = NpgsqlDbType.Jsonb,
                Column             = "data",
                BulkInsertPattern  = "writer.Write(serializer.ToJson(x), NpgsqlDbType.Jsonb);",
                BatchUpdatePattern = "*"
            });
        }
Ejemplo n.º 2
0
        public UpsertFunction(DocumentMapping mapping)
        {
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }

            _functionName             = mapping.UpsertFunction;
            _tableName                = mapping.Table;
            _primaryKeyConstraintName = "pk_" + mapping.Table.Name;

            var idType   = mapping.IdMember.GetMemberType();
            var pgIdType = TypeMappings.GetPgType(idType);

            Arguments.Add(new UpsertArgument
            {
                Arg          = "docId",
                PostgresType = pgIdType,
                Column       = "id",
                Members      = new[] { mapping.IdMember }
            });

            Arguments.Add(new DocJsonBodyArgument());

            Arguments.AddRange(mapping.DuplicatedFields.Select(x => x.UpsertArgument));

            Arguments.Add(new VersionArgument());

            Arguments.Add(new DotNetTypeArgument());

            if (mapping.IsHierarchy())
            {
                Arguments.Add(new DocTypeArgument());
            }
        }
Ejemplo n.º 3
0
        public DocumentTable(DocumentMapping mapping) : base(mapping.Table)
        {
            var pgIdType = TypeMappings.GetPgType(mapping.IdMember.GetMemberType());

            AddPrimaryKey(new TableColumn("id", pgIdType));

            AddColumn("data", "jsonb", "NOT NULL");

            AddColumn <LastModifiedColumn>();
            AddColumn <VersionColumn>();
            AddColumn <DotNetTypeColumn>();

            foreach (var field in mapping.DuplicatedFields)
            {
                AddColumn(new DuplicatedFieldColumn(field));
            }

            if (mapping.IsHierarchy())
            {
                AddColumn(new DocumentTypeColumn(mapping));
            }

            if (mapping.DeleteStyle == DeleteStyle.SoftDelete)
            {
                AddColumn <DeletedColumn>();
                AddColumn <DeletedAtColumn>();
            }

            Indexes.AddRange(mapping.Indexes);
            ForeignKeys.AddRange(mapping.ForeignKeys);
        }
Ejemplo n.º 4
0
        public void execute_get_pg_type_custom_mappings_resolve_or_default_to_jsonb()
        {
            NpgsqlConnection.GlobalTypeMapper.MapComposite <MappedTarget>("varchar");

            TypeMappings.GetPgType(typeof(MappedTarget), EnumStorage.AsString).ShouldBe("varchar");
            TypeMappings.GetPgType(typeof(UnmappedTarget), EnumStorage.AsString).ShouldBe("jsonb");
        }
Ejemplo n.º 5
0
        public TableDefinition StorageTable()
        {
            var pgIdType = TypeMappings.GetPgType(_mapping.IdMember.GetMemberType());
            var table    = new TableDefinition(_mapping.Table, new TableColumn("id", pgIdType));

            table.Columns.Add(new TableColumn("data", "jsonb")
            {
                Directive = "NOT NULL"
            });

            table.Columns.Add(new TableColumn(DocumentMapping.LastModifiedColumn, "timestamp with time zone")
            {
                Directive = "DEFAULT transaction_timestamp()"
            });
            table.Columns.Add(new TableColumn(DocumentMapping.VersionColumn, "uuid")
            {
                Directive = "NOT NULL"
            });
            table.Columns.Add(new TableColumn(DocumentMapping.DotNetTypeColumn, "varchar"));

            _mapping.DuplicatedFields.Select(x => x.ToColumn()).Each(x => table.Columns.Add(x));


            if (_mapping.IsHierarchy())
            {
                table.Columns.Add(new TableColumn(DocumentMapping.DocumentTypeColumn, "varchar"));
            }

            return(table);
        }
Ejemplo n.º 6
0
        public UpsertFunction(DocumentMapping mapping, DbObjectName identifier = null, bool disableConcurrency = false) : base(identifier ?? mapping.UpsertFunction)
        {
            _disableConcurrency = disableConcurrency;
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }

            _tableName = mapping.Table;


            var table = new DocumentTable(mapping);

            if (table.PrimaryKeys.Count > 1)
            {
                _primaryKeyConstraintName = mapping.Table.Name + "_pkey";
            }
            else
            {
                _primaryKeyConstraintName = "pk_" + mapping.Table.Name;
            }



            var idType   = mapping.IdMember.GetMemberType();
            var pgIdType = TypeMappings.GetPgType(idType);

            Arguments.Add(new UpsertArgument
            {
                Arg          = "docId",
                PostgresType = pgIdType,
                Column       = "id",
                Members      = new[] { mapping.IdMember }
            });

            Arguments.Add(new DocJsonBodyArgument());

            Arguments.AddRange(mapping.DuplicatedFields.Select(x => x.UpsertArgument));

            Arguments.Add(new VersionArgument());

            Arguments.Add(new DotNetTypeArgument());

            if (mapping.IsHierarchy())
            {
                Arguments.Add(new DocTypeArgument());
            }

            if (mapping.UseOptimisticConcurrency)
            {
                Arguments.Add(new CurrentVersionArgument());
            }

            if (mapping.TenancyStyle == TenancyStyle.Conjoined)
            {
                Arguments.Add(new TenantIdArgument());
                _tenantWhereClause    = $"{_tableName.QualifiedName}.{TenantIdColumn.Name} = {TenantIdArgument.ArgName}";
                _andTenantWhereClause = $" and {_tenantWhereClause}";
            }
        }
Ejemplo n.º 7
0
        public StreamTableColumn(string name, Expression <Func <StreamAction, object> > memberExpression) : base(name, "varchar")
        {
            _memberExpression = memberExpression;
            _member           = FindMembers.Determine(memberExpression).Single();
            var memberType = _member.GetMemberType();

            Type         = TypeMappings.GetPgType(memberType, EnumStorage.AsInteger);
            NpgsqlDbType = TypeMappings.ToDbType(memberType);
        }
Ejemplo n.º 8
0
        public DictionaryField(string dataLocator, Casing casing, EnumStorage enumStorage, MemberInfo[] members) : base(dataLocator, "JSONB", casing, members)
        {
            TypedLocator         = $"CAST({RawLocator} as {PgType})";
            _intermediateLocator = RawLocator.Replace("->>", "->");
            var valueType = FieldType.GenericTypeArguments[1];

            _isStringValue = valueType == typeof(string);
            _valuePgType   = TypeMappings.GetPgType(valueType, enumStorage);
        }
Ejemplo n.º 9
0
        protected Field(EnumStorage enumStorage, MemberInfo[] members)
        {
            Members    = members;
            MemberName = members.Select(x => x.Name).Join("");

            FieldType = members.Last().GetMemberType();

            PgType = TypeMappings.GetPgType(FieldType, enumStorage);
        }
Ejemplo n.º 10
0
        protected Field(MemberInfo[] members)
        {
            Members    = members;
            MemberName = members.Select(x => x.Name).Join("");

            MemberType = members.Last().GetMemberType();

            PgType = TypeMappings.GetPgType(MemberType);
        }
Ejemplo n.º 11
0
        public DuplicatedField(EnumStorage enumStorage, IField innerField,
                               bool useTimestampWithoutTimeZoneForDateTime = true, bool notNull = false)
        {
            InnerField = innerField;
            MemberName = InnerField.Members.Select(x => x.Name).Join("");
            NotNull    = notNull;
            ColumnName = MemberName.ToTableAlias();
            this.useTimestampWithoutTimeZoneForDateTime = useTimestampWithoutTimeZoneForDateTime;

            PgType = TypeMappings.GetPgType(FieldType, enumStorage);

            if (FieldType.IsEnum)
            {
                if (enumStorage == EnumStorage.AsString)
                {
                    DbType = NpgsqlDbType.Varchar;
                    PgType = "varchar";

                    _parseObject = expression =>
                    {
                        var raw = expression.Value();
                        if (raw == null)
                        {
                            return(null);
                        }
                        return(Enum.GetName(FieldType, raw));
                    };
                }
                else
                {
                    DbType = NpgsqlDbType.Integer;
                    PgType = "integer";
                }
            }
            else if (FieldType.IsDateTime())
            {
                PgType = this.useTimestampWithoutTimeZoneForDateTime
                    ? "timestamp without time zone"
                    : "timestamp with time zone";
                DbType = this.useTimestampWithoutTimeZoneForDateTime
                    ? NpgsqlDbType.Timestamp
                    : NpgsqlDbType.TimestampTz;
            }
            else if (FieldType == typeof(DateTimeOffset) || FieldType == typeof(DateTimeOffset?))
            {
                PgType = "timestamp with time zone";
                DbType = NpgsqlDbType.TimestampTz;
            }
            else
            {
                DbType = TypeMappings.ToDbType(FieldType);
            }
        }
Ejemplo n.º 12
0
        protected IField resolveField(MemberInfo[] members)
        {
            foreach (var source in _options.FieldSources)
            {
                if (source.TryResolve(_dataLocator, _options, _serializer, _documentType, members, out var field))
                {
                    return(field);
                }
            }

            var fieldType = members.Last().GetMemberType();

            if (fieldType == typeof(string))
            {
                return(new StringField(_dataLocator, _serializer.Casing, members));
            }



            if (fieldType.IsEnum)
            {
                return(_serializer.EnumStorage == EnumStorage.AsInteger
                    ? (IField) new EnumAsIntegerField(_dataLocator, _serializer.Casing, members)
                    : new EnumAsStringField(_dataLocator, _serializer.Casing, members));
            }

            if (fieldType == typeof(DateTime) || fieldType == typeof(DateTime?))
            {
                return(new DateTimeField(_dataLocator, _options.DatabaseSchemaName, _serializer.Casing, members));
            }

            if (fieldType == typeof(DateTimeOffset) || fieldType == typeof(DateTimeOffset?))
            {
                return(new DateTimeOffsetField(_dataLocator, _options.DatabaseSchemaName, _serializer.Casing, members));
            }



            var pgType = TypeMappings.GetPgType(fieldType, _serializer.EnumStorage);


            if (pgType.IsNotEmpty())
            {
                if (fieldType.IsArray || fieldType.Closes(typeof(IList <>)))
                {
                    return(new ArrayField(_dataLocator, pgType, _serializer.Casing, members));
                }

                return(new SimpleCastField(_dataLocator, pgType, _serializer.Casing, members));
            }

            throw new NotSupportedException($"Marten does not support Linq expressions for this member. Was {_documentType.FullName}.{members.Select(x => x.Name).Join(".")}");
        }
Ejemplo n.º 13
0
        protected Field(EnumStorage enumStorage, MemberInfo[] members, bool notNull = false)
        {
            Members    = members;
            MemberName = members.Select(x => x.Name).Join("");

            MemberType = members.Last().GetMemberType();

            PgType       = TypeMappings.GetPgType(MemberType, enumStorage);
            _enumStorage = enumStorage;

            NotNull = notNull;
        }
Ejemplo n.º 14
0
        public void add_type_by_dotnet_type_and_name()
        {
            var table = new Table("mytable");

            table.AddColumn <int>("number");
            var column = table.Columns.Single();

            column
            .Type.ShouldBe(TypeMappings.GetPgType(typeof(int), EnumStorage.AsInteger));

            table.Columns.ShouldContain(column);
        }
Ejemplo n.º 15
0
        public DocumentTable(DocumentMapping mapping) : base(mapping.Table)
        {
            // validate to ensure document has an Identity field or property
            mapping.Validate();

            var pgIdType   = TypeMappings.GetPgType(mapping.IdMember.GetMemberType());
            var pgTextType = TypeMappings.GetPgType(string.Empty.GetType());

            var idColumn = new TableColumn("id", pgIdType);

            if (mapping.TenancyStyle == TenancyStyle.Conjoined)
            {
                AddPrimaryKeys(new List <TableColumn>
                {
                    idColumn,
                    new TenantIdColumn()
                });

                Indexes.Add(new IndexDefinition(mapping, TenantIdColumn.Name));
            }
            else
            {
                AddPrimaryKey(idColumn);
            }

            AddColumn("data", "jsonb", "NOT NULL");

            AddColumn <LastModifiedColumn>();
            AddColumn <VersionColumn>();
            AddColumn <DotNetTypeColumn>();

            foreach (var field in mapping.DuplicatedFields)
            {
                AddColumn(new DuplicatedFieldColumn(field));
            }

            if (mapping.IsHierarchy())
            {
                AddColumn(new DocumentTypeColumn(mapping));
            }

            if (mapping.DeleteStyle == DeleteStyle.SoftDelete)
            {
                AddColumn <DeletedColumn>();
                Indexes.Add(new IndexDefinition(mapping, DocumentMapping.DeletedColumn));
                AddColumn <DeletedAtColumn>();
            }


            Indexes.AddRange(mapping.Indexes);
            ForeignKeys.AddRange(mapping.ForeignKeys);
        }
Ejemplo n.º 16
0
        private IField createFieldByFieldType(MemberInfo[] members, Type fieldType)
        {
            if (fieldType == typeof(string))
            {
                return(new StringField(_dataLocator, _serializer.Casing, members));
            }

            if (fieldType.Closes(typeof(IDictionary <,>)))
            {
                return(new DictionaryField(_dataLocator, _serializer.Casing, _serializer.EnumStorage, members));
            }

            if (fieldType.IsEnum)
            {
                return(_serializer.EnumStorage == EnumStorage.AsInteger
                    ? (IField) new EnumAsIntegerField(_dataLocator, _serializer.Casing, members)
                    : new EnumAsStringField(_dataLocator, _serializer.Casing, members));
            }

            if (fieldType == typeof(DateTime))
            {
                return(new DateTimeField(_dataLocator, _options.DatabaseSchemaName, _serializer.Casing, members));
            }

            if (fieldType == typeof(DateTimeOffset))
            {
                return(new DateTimeOffsetField(_dataLocator, _options.DatabaseSchemaName, _serializer.Casing, members));
            }


            var pgType = TypeMappings.GetPgType(fieldType, _serializer.EnumStorage);


            if (fieldType.Closes(typeof(IDictionary <,>)))
            {
                return(new SimpleCastField(_dataLocator, "JSONB", _serializer.Casing, members));
            }

            if (isEnumerable(fieldType))
            {
                return(new ArrayField(_dataLocator, pgType, _serializer, members));
            }

            if (pgType.IsNotEmpty())
            {
                return(new SimpleCastField(_dataLocator, pgType, _serializer.Casing, members));
            }

            throw new NotSupportedException(
                      $"Marten does not support Linq expressions for this member. Was {_documentType.FullName}.{members.Select(x => x.Name).Join(".")}");
        }
Ejemplo n.º 17
0
        public TableDefinition StorageTable()
        {
            var pgIdType = TypeMappings.GetPgType(_mapping.IdMember.GetMemberType());
            var table    = new TableDefinition(_mapping.Table, new TableColumn("id", pgIdType));


            table.Columns.Add(new TableColumn("data", "jsonb")
            {
                Directive = "NOT NULL"
            });

            table.Columns.Add(new TableColumn(DocumentMapping.LastModifiedColumn, "timestamp with time zone")
            {
                Directive = "DEFAULT transaction_timestamp()"
            });

            table.Columns.Add(new TableColumn(DocumentMapping.VersionColumn, "uuid")
            {
                Directive = "NOT NULL default(md5(random()::text || clock_timestamp()::text)::uuid)"
            });

            table.Columns.Add(new TableColumn(DocumentMapping.DotNetTypeColumn, "varchar"));

            _mapping.DuplicatedFields.Select(x => x.ToColumn()).Each(x => table.Columns.Add(x));


            if (_mapping.IsHierarchy())
            {
                table.Columns.Add(new TableColumn(DocumentMapping.DocumentTypeColumn, "varchar")
                {
                    Directive = $"DEFAULT '{_mapping.AliasFor(_mapping.DocumentType)}'"
                });
            }

            if (_mapping.DeleteStyle == DeleteStyle.SoftDelete)
            {
                table.Columns.Add(new TableColumn(DocumentMapping.DeletedColumn, "boolean")
                {
                    Directive = "DEFAULT FALSE"
                });

                table.Columns.Add(new TableColumn(DocumentMapping.DeletedAtColumn, "timestamp with time zone")
                {
                    Directive = "NULL"
                });
            }

            return(table);
        }
Ejemplo n.º 18
0
        public ArrayField(string dataLocator, string pgType, Casing casing, MemberInfo[] members) : base(dataLocator, pgType, casing, members)
        {
            var rawLocator = RawLocator;

            RawLocator = $"CAST({rawLocator} as jsonb)";

            if (PgType == "jsonb[]")
            {
                PgType = "jsonb";
            }

            TypedLocator = $"CAST({rawLocator} as {PgType})";

            var collectionType = members.Last().GetMemberType();
            var elementType    = collectionType.DetermineElementType();
            var innerPgType    = TypeMappings.GetPgType(elementType, EnumStorage.AsInteger);

            LocatorForIncludedDocumentId =
                $"unnest(CAST(ARRAY(SELECT jsonb_array_elements_text(CAST({rawLocator} as jsonb))) as {innerPgType}[]))";
        }
Ejemplo n.º 19
0
        public virtual TableDefinition ToTable(IDocumentSchema schema) // take in schema so that you
        // can do foreign keys
        {
            var pgIdType = TypeMappings.GetPgType(IdMember.GetMemberType());
            var table    = new TableDefinition(TableName, new TableColumn("id", pgIdType));

            table.Columns.Add(new TableColumn("data", "jsonb")
            {
                Directive = "NOT NULL"
            });

            _fields.Values.OfType <DuplicatedField>().Select(x => x.ToColumn(schema)).Each(x => table.Columns.Add(x));


            if (IsHierarchy())
            {
                table.Columns.Add(new TableColumn(DocumentTypeColumn, "varchar"));
            }

            return(table);
        }
Ejemplo n.º 20
0
        public ArrayField(string dataLocator, string pgType, ISerializer serializer, MemberInfo[] members) : base(dataLocator, pgType, serializer.Casing, members)
        {
            var rawLocator = RawLocator;

            RawLocator = $"CAST({rawLocator} as jsonb)";

            var collectionType = members.Last().GetMemberType();

            ElementType = collectionType.DetermineElementType();
            var innerPgType = TypeMappings.GetPgType(ElementType, EnumStorage.AsInteger);


            if (TypeMappings.HasTypeMapping(ElementType))
            {
                PgType = innerPgType + "[]";
            }

            if (PgType == "jsonb[]")
            {
                PgType = "jsonb";
            }



            TypedLocator = $"CAST({rawLocator} as {PgType})";



            LocatorForIncludedDocumentId =
                $"unnest(CAST(ARRAY(SELECT jsonb_array_elements_text(CAST({rawLocator} as jsonb))) as {innerPgType}[]))";

            if (PgType.EqualsIgnoreCase("JSONB"))
            {
                LocatorForFlattenedElements = $"unnest(CAST(ARRAY(SELECT jsonb_array_elements(CAST({rawLocator} as jsonb))) as jsonb[]))";
            }
            else
            {
                LocatorForFlattenedElements = LocatorForIncludedDocumentId;
            }
        }
Ejemplo n.º 21
0
        public override ISqlFragment CreateComparison(string op, ConstantExpression value, Expression memberExpression)
        {
            var key     = memberExpression.As <MethodCallExpression>().Arguments[0].As <ConstantExpression>().Value;
            var locator = $"{RawLocator.Replace("->>", "->")} ->> '{key}'";


            if (value.Value == null)
            {
                return(op == "=" ? (ISqlFragment) new IsNullFilter(this) : new IsNotNullFilter(this));
            }
            else
            {
                if (_valueIsObject)
                {
                    var pgType = TypeMappings.GetPgType(value.Value.GetType(), _enumStorage);
                    locator = $"CAST({locator} as {pgType})";
                }
            }

            var def = new CommandParameter(value);

            return(new ComparisonFilter(new WhereFragment(locator), def, op));
        }
 public static string ToLocator(ISerializer serializer)
 {
     return($"CAST(data as {TypeMappings.GetPgType(typeof(T), serializer.EnumStorage)})");
 }
Ejemplo n.º 23
0
 public void execute_get_pg_type_default_mappings_resolve()
 {
     TypeMappings.GetPgType(typeof(long), EnumStorage.AsString).ShouldBe("bigint");
     TypeMappings.GetPgType(typeof(DateTime), EnumStorage.AsString).ShouldBe("timestamp without time zone");
 }
Ejemplo n.º 24
0
        public UpsertFunction(DocumentMapping mapping, DbObjectName identifier = null, bool disableConcurrency = false) : base(identifier ?? mapping.UpsertFunction)
        {
            _mapping            = mapping;
            _disableConcurrency = disableConcurrency;
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }

            _tableName = mapping.TableName;

            // TODO -- it'd be nice to not need this here.
            var table = new DocumentTable(mapping);

            if (table.PrimaryKeys.Count > 1)
            {
                _primaryKeyConstraintName = mapping.TableName.Name + "_pkey";
            }
            else
            {
                _primaryKeyConstraintName = "pk_" + mapping.TableName.Name;
            }

            var idType   = mapping.IdMember.GetMemberType();
            var pgIdType = TypeMappings.GetPgType(idType, mapping.EnumStorage);

            Arguments.Add(new UpsertArgument
            {
                Arg          = "docId",
                PostgresType = pgIdType,
                Column       = "id",
                Members      = new[] { mapping.IdMember }
            });

            Arguments.Add(new DocJsonBodyArgument());

            Arguments.AddRange(mapping.DuplicatedFields.Where(x => !x.OnlyForSearching).Select(x => x.UpsertArgument));

            // TODO -- see the columns below
            if (mapping.Metadata.Version.Enabled)
            {
                Arguments.Add(new VersionArgument());
            }

            if (mapping.Metadata.DotNetType.Enabled)
            {
                Arguments.Add(new DotNetTypeArgument());
            }

            AddIfActive(mapping.Metadata.CorrelationId);
            AddIfActive(mapping.Metadata.CausationId);
            AddIfActive(mapping.Metadata.LastModifiedBy);
            AddIfActive(mapping.Metadata.Headers);


            if (mapping.IsHierarchy())
            {
                Arguments.Add(new DocTypeArgument());
            }

            if (mapping.UseOptimisticConcurrency)
            {
                Arguments.Add(new CurrentVersionArgument());
            }

            if (mapping.TenancyStyle == TenancyStyle.Conjoined)
            {
                Arguments.Add(new TenantIdArgument());
                _tenantWhereClause    = $"{_tableName.QualifiedName}.{TenantIdColumn.Name} = {TenantIdArgument.ArgName}";
                _andTenantWhereClause = $" and {_tenantWhereClause}";
            }
        }
Ejemplo n.º 25
0
 public IdColumn(DocumentMapping mapping) : base("id",
                                                 TypeMappings.GetPgType(mapping.IdMember.GetMemberType(), mapping.EnumStorage))
 {
 }