forked from npgsql/npgsql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTypeMapperBase.cs
More file actions
124 lines (95 loc) · 4.35 KB
/
TypeMapperBase.cs
File metadata and controls
124 lines (95 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
using System;
using System.Collections.Generic;
using System.Reflection;
using Npgsql.TypeHandlers;
using Npgsql.TypeHandlers.CompositeHandlers;
using NpgsqlTypes;
namespace Npgsql.TypeMapping
{
abstract class TypeMapperBase : INpgsqlTypeMapper
{
internal Dictionary<string, NpgsqlTypeMapping> Mappings { get; } = new Dictionary<string, NpgsqlTypeMapping>();
public INpgsqlNameTranslator DefaultNameTranslator { get; }
protected TypeMapperBase(INpgsqlNameTranslator defaultNameTranslator)
{
if (defaultNameTranslator == null)
throw new ArgumentNullException(nameof(defaultNameTranslator));
DefaultNameTranslator = defaultNameTranslator;
}
#region Mapping management
public virtual INpgsqlTypeMapper AddMapping(NpgsqlTypeMapping mapping)
{
if (Mappings.ContainsKey(mapping.PgTypeName))
RemoveMapping(mapping.PgTypeName);
Mappings[mapping.PgTypeName] = mapping;
return this;
}
public virtual bool RemoveMapping(string pgTypeName) => Mappings.Remove(pgTypeName);
IEnumerable<NpgsqlTypeMapping> INpgsqlTypeMapper.Mappings => Mappings.Values;
public abstract void Reset();
#endregion Mapping management
#region Enum mapping
public INpgsqlTypeMapper MapEnum<TEnum>(string? pgName = null, INpgsqlNameTranslator? nameTranslator = null)
where TEnum : struct, Enum
{
if (pgName != null && pgName.Trim() == "")
throw new ArgumentException("pgName can't be empty", nameof(pgName));
if (nameTranslator == null)
nameTranslator = DefaultNameTranslator;
if (pgName == null)
pgName = GetPgName<TEnum>(nameTranslator);
return AddMapping(new NpgsqlTypeMappingBuilder
{
PgTypeName = pgName,
ClrTypes = new[] { typeof(TEnum) },
TypeHandlerFactory = new EnumTypeHandlerFactory<TEnum>(nameTranslator)
}.Build());
}
public bool UnmapEnum<TEnum>(string? pgName = null, INpgsqlNameTranslator? nameTranslator = null)
where TEnum : struct, Enum
{
if (pgName != null && pgName.Trim() == "")
throw new ArgumentException("pgName can't be empty", nameof(pgName));
if (nameTranslator == null)
nameTranslator = DefaultNameTranslator;
if (pgName == null)
pgName = GetPgName<TEnum>(nameTranslator);
return RemoveMapping(pgName);
}
#endregion Enum mapping
#region Composite mapping
public INpgsqlTypeMapper MapComposite<T>(string? pgName = null, INpgsqlNameTranslator? nameTranslator = null)
{
if (pgName != null && pgName.Trim() == "")
throw new ArgumentException("pgName can't be empty", nameof(pgName));
if (nameTranslator == null)
nameTranslator = DefaultNameTranslator;
if (pgName == null)
pgName = GetPgName<T>(nameTranslator);
return AddMapping(new NpgsqlTypeMappingBuilder
{
PgTypeName = pgName,
ClrTypes = new[] { typeof(T) },
TypeHandlerFactory = new CompositeTypeHandlerFactory<T>(nameTranslator)
}.Build());
}
public bool UnmapComposite<T>(string? pgName = null, INpgsqlNameTranslator? nameTranslator = null)
{
if (pgName != null && pgName.Trim() == "")
throw new ArgumentException("pgName can't be empty", nameof(pgName));
if (nameTranslator == null)
nameTranslator = DefaultNameTranslator;
if (pgName == null)
pgName = GetPgName<T>(nameTranslator);
return RemoveMapping(pgName);
}
#endregion Composite mapping
#region Misc
// TODO: why does ReSharper think `GetCustomAttribute<T>` is non-nullable?
// ReSharper disable once ConstantConditionalAccessQualifier ConstantNullCoalescingCondition
static string GetPgName<T>(INpgsqlNameTranslator nameTranslator)
=> typeof(T).GetCustomAttribute<PgNameAttribute>()?.PgName
?? nameTranslator.TranslateTypeName(typeof(T).Name);
#endregion Misc
}
}