Exemple #1
0
 public virtual INpgsqlTypeMapper AddMapping(NpgsqlTypeMapping mapping)
 {
     if (Mappings.ContainsKey(mapping.PgTypeName))
     {
         RemoveMapping(mapping.PgTypeName);
     }
     Mappings[mapping.PgTypeName] = mapping;
     return(this);
 }
Exemple #2
0
        public override INpgsqlTypeMapper AddMapping(NpgsqlTypeMapping mapping)
        {
            CheckReady();

            base.AddMapping(mapping);
            BindType(mapping, _connector, true);
            ChangeCounter = -1;
            return(this);
        }
Exemple #3
0
        void BindType(NpgsqlTypeMapping mapping, NpgsqlConnector connector, bool throwOnError)
        {
            // Binding can occur at two different times:
            // 1. When a user adds a mapping for a specific connection (and exception should bubble up to them)
            // 2. When binding the global mappings, in which case we want to log rather than throw
            // (i.e. missing database type for some unused defined binding shouldn't fail the connection)

            var pgName = mapping.PgTypeName;
            var found  = pgName.IndexOf('.') == -1
                ? DatabaseInfo.ByName.TryGetValue(pgName, out var pgType)  // No dot, partial type name
                : DatabaseInfo.ByFullName.TryGetValue(pgName, out pgType); // Full type name with namespace

            if (!found)
            {
                var msg = $"A PostgreSQL type with the name {mapping.PgTypeName} was not found in the database";
                if (throwOnError)
                {
                    throw new ArgumentException(msg);
                }
                Log.Debug(msg);
                return;
            }
            else if (pgType == null)
            {
                var msg = $"More than one PostgreSQL type was found with the name {mapping.PgTypeName}, please specify a full name including schema";
                if (throwOnError)
                {
                    throw new ArgumentException(msg);
                }
                Log.Debug(msg);
                return;
            }
            else if (pgType is PostgresDomainType)
            {
                var msg = "Cannot add a mapping to a PostgreSQL domain type";
                if (throwOnError)
                {
                    throw new NotSupportedException(msg);
                }
                Log.Debug(msg);
                return;
            }

            var handler = mapping.TypeHandlerFactory.Create(pgType, connector.Connection);

            BindType(handler, pgType, mapping.NpgsqlDbType, mapping.DbTypes, mapping.ClrTypes);
        }
Exemple #4
0
 void BindType(NpgsqlTypeMapping mapping, NpgsqlConnector connector, bool throwOnError)
 {
     // Binding can occur at two different times:
     // 1. When a user adds a mapping for a specific connection (and exception should bubble up to them)
     // 2. When binding the global mappings, in which case we want to log rather than throw
     // (i.e. missing database type for some unused defined binding shouldn't fail the connection)
     try
     {
         DoBindType(mapping, connector);
     }
     catch (Exception e)
     {
         if (throwOnError)
         {
             throw;
         }
         Log.Warn($"Exception while binding type {mapping.PgTypeName}", e);
     }
 }
Exemple #5
0
        public override INpgsqlTypeMapper AddMapping(NpgsqlTypeMapping mapping)
        {
            Lock.EnterWriteLock();
            try
            {
                base.AddMapping(mapping);
                RecordChange();

                if (mapping.NpgsqlDbType.HasValue)
                {
                    foreach (var dbType in mapping.DbTypes)
                    {
                        _dbTypeToNpgsqlDbType[dbType] = mapping.NpgsqlDbType.Value;
                    }

                    if (mapping.InferredDbType.HasValue)
                    {
                        _npgsqlDbTypeToDbType[mapping.NpgsqlDbType.Value] = mapping.InferredDbType.Value;
                    }

                    foreach (var clrType in mapping.ClrTypes)
                    {
                        _typeToNpgsqlDbType[clrType] = mapping.NpgsqlDbType.Value;
                    }
                }

                if (mapping.InferredDbType.HasValue)
                {
                    foreach (var clrType in mapping.ClrTypes)
                    {
                        _typeToDbType[clrType] = mapping.InferredDbType.Value;
                    }
                }

                return(this);
            }
            finally
            {
                Lock.ExitWriteLock();
            }
        }
Exemple #6
0
        void DoBindType(NpgsqlTypeMapping mapping, NpgsqlConnector connector)
        {
            var pgName = mapping.PgTypeName;
            var found  = pgName.IndexOf('.') == -1
                ? DatabaseInfo.ByName.TryGetValue(pgName, out var pgType)  // No dot, partial type name
                : DatabaseInfo.ByFullName.TryGetValue(pgName, out pgType); // Full type name with namespace

            if (!found)
            {
                throw new ArgumentException($"A PostgreSQL type with the name {mapping.PgTypeName} was not found in the database");
            }
            if (pgType == null)
            {
                throw new ArgumentException($"More than one PostgreSQL type was found with the name {mapping.PgTypeName}, please specify a full name including schema");
            }
            if (pgType is PostgresDomainType)
            {
                throw new NotSupportedException("Cannot add a mapping to a PostgreSQL domain type");
            }

            var handler = mapping.TypeHandlerFactory.Create(pgType, connector.Connection);

            BindType(handler, pgType, mapping.NpgsqlDbType, mapping.DbTypes, mapping.ClrTypes);
        }
Exemple #7
0
        void BindType(NpgsqlTypeMapping mapping, NpgsqlConnector connector, bool externalCall)
        {
            // Binding can occur at two different times:
            // 1. When a user adds a mapping for a specific connection (and exception should bubble up to them)
            // 2. When binding the global mappings, in which case we want to log rather than throw
            // (i.e. missing database type for some unused defined binding shouldn't fail the connection)

            var pgName = mapping.PgTypeName;

            PostgresType pgType = null;

            if (pgName.IndexOf('.') > -1)
            {
                DatabaseInfo.ByFullName.TryGetValue(pgName, out pgType);  // Full type name with namespace
            }
            else if (DatabaseInfo.ByName.TryGetValue(pgName, out pgType)) // No dot, partial type name
            {
                if (pgType is null)
                {
                    // If the name was found but the value is null, that means that there are
                    // two db types with the same name (different schemas).
                    // Try to fall back to pg_catalog, otherwise fail.
                    if (!DatabaseInfo.ByFullName.TryGetValue($"pg_catalog.{pgName}", out pgType))
                    {
                        var msg = $"More than one PostgreSQL type was found with the name {mapping.PgTypeName}, please specify a full name including schema";
                        if (externalCall)
                        {
                            throw new ArgumentException(msg);
                        }
                        Log.Debug(msg);
                        return;
                    }
                }
            }

            if (pgType is null)
            {
                var msg = $"A PostgreSQL type with the name {mapping.PgTypeName} was not found in the database";
                if (externalCall)
                {
                    throw new ArgumentException(msg);
                }
                Log.Debug(msg);
                return;
            }
            if (pgType is PostgresDomainType)
            {
                var msg = "Cannot add a mapping to a PostgreSQL domain type";
                if (externalCall)
                {
                    throw new NotSupportedException(msg);
                }
                Log.Debug(msg);
                return;
            }

            var handler = mapping.TypeHandlerFactory.Create(pgType, connector.Connection);

            BindType(handler, pgType, mapping.NpgsqlDbType, mapping.DbTypes, mapping.ClrTypes);

            if (!externalCall)
            {
                return;
            }

            foreach (var domain in DatabaseInfo.DomainTypes)
            {
                if (domain.BaseType.OID == pgType.OID)
                {
                    _byOID[domain.OID] = handler;
                    if (domain.Array != null)
                    {
                        BindType(handler.CreateArrayHandler(domain.Array), domain.Array);
                    }
                }
            }
        }
Exemple #8
0
 public abstract INpgsqlTypeMapper AddMapping(NpgsqlTypeMapping mapping);