<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.RegularExpressions;
using Baseline;
using Baseline.Reflection;
using Marten.Linq;
using Marten.Schema.Arguments;
using Marten.Schema.Identity;
using Marten.Schema.Identity.Sequences;
using Marten.Services.Includes;
using Marten.Storage;
using Marten.Util;
using Remotion.Linq;

namespace Marten.Schema
{
    public class DocumentMapping : FieldCollection, IDocumentMapping, IQueryableDocument, IFeatureSchema
    {
        public const string BaseAlias = "BASE";
        public const string TablePrefix = "mt_doc_";
        public const string UpsertPrefix = "mt_upsert_";
        public const string InsertPrefix = "mt_insert_";
        public const string UpdatePrefix = "mt_update_";
        public const string OverwritePrefix = "mt_overwrite_";
        public const string DocumentTypeColumn = "mt_doc_type";
        public const string MartenPrefix = "mt_";
        public const string LastModifiedColumn = "mt_last_modified";
        public const string DotNetTypeColumn = "mt_dotnet_type";
        public const string VersionColumn = "mt_version";
        public const string DeletedColumn = "mt_deleted";
        public const string DeletedAtColumn = "mt_deleted_at";

        private static readonly Regex _aliasSanitizer = new Regex("<|>", RegexOptions.Compiled);
        
        private readonly StoreOptions _storeOptions;

        private readonly IList<SubClassMapping> _subClasses = new List<SubClassMapping>();
        private string _alias;
        private string _databaseSchemaName;
        private MemberInfo _idMember;


        public DocumentMapping(Type documentType, StoreOptions storeOptions) : base("d.data", documentType, storeOptions)
        {
            _storeOptions = storeOptions ?? throw new ArgumentNullException(nameof(storeOptions));

            DocumentType = documentType ?? throw new ArgumentNullException(nameof(documentType));
            Alias = defaultDocumentAliasName(documentType);

            IdMember = FindIdMember(documentType);

            _storeOptions.applyPolicies(this);

            applyAnyMartenAttributes(documentType);
        }

        public TenancyStyle TenancyStyle { get; set; } = TenancyStyle.Single;


        public MemberInfo VersionMember
        {
            get => _versionMember;
            set
            {
                if (value == null)
                {
                    UseOptimisticConcurrency = false;
                }
                else
                {
                    if (value.GetMemberType() != typeof(Guid)) throw new ArgumentOutOfRangeException(nameof(value), "The Version member has to be of type Guid");
                    UseOptimisticConcurrency = true;
                    _versionMember = value;
                }
            }
        }

        private void applyAnyMartenAttributes(Type documentType)
        {
            documentType.ForAttribute<MartenAttribute>(att => att.Modify(this));

            documentType.GetProperties()
                .Where(x => TypeMappings.HasTypeMapping(x.PropertyType))
                .Each(prop => { prop.ForAttribute<MartenAttribute>(att => att.Modify(this, prop)); });

            documentType.GetFields()
                .Where(x => TypeMappings.HasTypeMapping(x.FieldType))
                .Each(fieldInfo => { fieldInfo.ForAttribute<MartenAttribute>(att => att.Modify(this, fieldInfo)); });
        }

        public bool UseOptimisticConcurrency { get; set; } = false;

        public IList<IIndexDefinition> Indexes { get; } = new List<IIndexDefinition>();

        public IList<ForeignKeyDefinition> ForeignKeys { get; } = new List<ForeignKeyDefinition>();

        public IEnumerable<SubClassMapping> SubClasses => _subClasses;

        public DbObjectName UpsertFunction => new DbObjectName(DatabaseSchemaName, $"{UpsertPrefix}{_alias}");
        public DbObjectName InsertFunction => new DbObjectName(DatabaseSchemaName, $"{InsertPrefix}{_alias}");
        public DbObjectName UpdateFunction => new DbObjectName(DatabaseSchemaName, $"{UpdatePrefix}{_alias}");<commit_msg>Fix for GH-931 - not to use typemapping check for duplicate field attribute<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.RegularExpressions;
using Baseline;
using Baseline.Reflection;
using Marten.Linq;
using Marten.Schema.Arguments;
using Marten.Schema.Identity;
using Marten.Schema.Identity.Sequences;
using Marten.Services.Includes;
using Marten.Storage;
using Marten.Util;
using Remotion.Linq;

namespace Marten.Schema
{
    public class DocumentMapping : FieldCollection, IDocumentMapping, IQueryableDocument, IFeatureSchema
    {
        public const string BaseAlias = "BASE";
        public const string TablePrefix = "mt_doc_";
        public const string UpsertPrefix = "mt_upsert_";
        public const string InsertPrefix = "mt_insert_";
        public const string UpdatePrefix = "mt_update_";
        public const string OverwritePrefix = "mt_overwrite_";
        public const string DocumentTypeColumn = "mt_doc_type";
        public const string MartenPrefix = "mt_";
        public const string LastModifiedColumn = "mt_last_modified";
        public const string DotNetTypeColumn = "mt_dotnet_type";
        public const string VersionColumn = "mt_version";
        public const string DeletedColumn = "mt_deleted";
        public const string DeletedAtColumn = "mt_deleted_at";

        private static readonly Regex _aliasSanitizer = new Regex("<|>", RegexOptions.Compiled);
        
        private readonly StoreOptions _storeOptions;

        private readonly IList<SubClassMapping> _subClasses = new List<SubClassMapping>();
        private string _alias;
        private string _databaseSchemaName;
        private MemberInfo _idMember;


        public DocumentMapping(Type documentType, StoreOptions storeOptions) : base("d.data", documentType, storeOptions)
        {
            _storeOptions = storeOptions ?? throw new ArgumentNullException(nameof(storeOptions));

            DocumentType = documentType ?? throw new ArgumentNullException(nameof(documentType));
            Alias = defaultDocumentAliasName(documentType);

            IdMember = FindIdMember(documentType);

            _storeOptions.applyPolicies(this);

            applyAnyMartenAttributes(documentType);
        }

        public TenancyStyle TenancyStyle { get; set; } = TenancyStyle.Single;


        public MemberInfo VersionMember
        {
            get => _versionMember;
            set
            {
                if (value == null)
                {
                    UseOptimisticConcurrency = false;
                }
                else
                {
                    if (value.GetMemberType() != typeof(Guid)) throw new ArgumentOutOfRangeException(nameof(value), "The Version member has to be of type Guid");
                    UseOptimisticConcurrency = true;
                    _versionMember = value;
                }
            }
        }

        private void applyAnyMartenAttributes(Type documentType)
        {
            documentType.ForAttribute<MartenAttribute>(att => att.Modify(this));

            documentType.GetProperties()
                .Where(x => !x.HasAttribute<DuplicateFieldAttribute>() && TypeMappings.HasTypeMapping(x.PropertyType))
                .Each(prop => { prop.ForAttribute<MartenAttribute>(att => att.Modify(this, prop)); });

            documentType.GetFields()
                .Where(x => !x.HasAttribute<DuplicateFieldAttribute>() && TypeMappings.HasTypeMapping(x.FieldType))
                .Each(fieldInfo => { fieldInfo.ForAttribute<MartenAttribute>(att => att.Modify(this, fieldInfo)); });

            // DuplicateFieldAttribute does not require TypeMappings check
            documentType.GetProperties()
                .Where(x => x.HasAttribute<DuplicateFieldAttribute>())
                .Each(prop => { prop.ForAttribute<DuplicateFieldAttribute>(att => att.Modify(this, prop)); });

            documentType.GetFields()
                .Where(x => x.HasAttribute<DuplicateFieldAttribute>())
                .Each(fieldInfo => { fieldInfo.ForAttribute<DuplicateFieldAttribute>(att => att.Modify(this, fieldInfo)); });
        }

        public bool UseOptimisticConcurrency { get; set; } = false;

        public IList<IIndexDefinition> Indexes { get; } = new List<IIndexDefinition>();

        public IList<ForeignKeyDefinition> ForeignKeys { get; } = new List<ForeignKeyDefinition>();

        public IEnumerable<SubClassMapping> SubClasses => _subClasses;

        public DbObjectName UpsertFunction => new DbObjectName(DatabaseSchemaName, $"{UpsertPrefix}{_alias}");
        public DbObjectName InsertFunction => new DbObjectName(DatabaseSchemaName, $"{InsertPrefix}{_alias}");
        public DbObjectName UpdateFunction => new DbObjectName(DatabaseSchemaName, $"{UpdatePrefix}{_alias}");
{'fraction_non_alphanumeric': 0.08963401271093578, 'fraction_numerical': 0.0003287310979618672, 'mean_word_length': 2.8838297872340424, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4609234', 'n_tokens_mistral': 2351, 'n_tokens_neox': 2270, 'n_words': 544}