-
-
Notifications
You must be signed in to change notification settings - Fork 27
Add provider specific column types #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
c656d78
cf557ea
a0f01b3
ba702b7
525a05c
b2aecb9
bc80625
c08a55d
268bb58
3b32f80
602d507
e646095
4e4db59
a88f445
f38df21
f1d2d95
fd0e9a6
feaf2ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| module SqlHydra.Npgsql.NpgsqlSchemaProvider | ||
|
|
||
| open System.Data | ||
| open Npgsql | ||
| open NpgsqlTypes | ||
| open SqlHydra.Domain | ||
|
|
||
| let getSchema (cfg: Config) : Schema = | ||
|
|
@@ -59,6 +59,12 @@ let getSchema (cfg: Config) : Schema = | |
| |} | ||
| ) | ||
|
|
||
| let getDbColumnType = | ||
| function | ||
| | "json" -> { TypeName = nameof NpgsqlDbType; TypeValue = nameof NpgsqlDbType.Json } |> Some | ||
| | "jsonb" -> { TypeName = nameof NpgsqlDbType; TypeValue = nameof NpgsqlDbType.Jsonb } |> Some | ||
| | _ -> None | ||
|
|
||
| let tables = | ||
| sTables.Rows | ||
| |> Seq.cast<DataRow> | ||
|
|
@@ -87,6 +93,7 @@ let getSchema (cfg: Config) : Schema = | |
| |> Option.map (fun typeMapping -> | ||
| { | ||
| Column.Name = col.ColumnName | ||
| Column.DbColumnType = getDbColumnType col.ProviderTypeName | ||
|
||
| Column.IsNullable = col.IsNullable | ||
| Column.TypeMapping = typeMapping | ||
| Column.IsPK = pks.Contains(col.TableSchema, col.TableName, col.ColumnName) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,7 +5,16 @@ open SqlKata | |
|
|
||
| /// Contains methods that compile and read a query. | ||
| type QueryContext(conn: DbConnection, compiler: SqlKata.Compilers.Compiler) = | ||
|
|
||
| let setParameterDbType (param: DbParameter) (qp: QueryParameter) = | ||
| match qp.Type, compiler with | ||
| | Some type', :? SqlKata.Compilers.PostgresCompiler when type'.TypeName = "NpgsqlDbType" -> | ||
| let property = param.GetType().GetProperty("NpgsqlDbType") | ||
| let dbTypeSetter = property.GetSetMethod() | ||
|
|
||
| let value = System.Enum.Parse(property.PropertyType, type'.TypeValue) | ||
| dbTypeSetter.Invoke(param, [|value|]) |> ignore | ||
| | _ -> () | ||
|
|
||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to add a handler here for SQL Server as well: | Some type', :? SqlKata.Compilers.SqlServerCompiler when type'.TypeName = "SqlDbType" ->
let property = param.GetType().GetProperty("SqlDbType")
...
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What you have in So this should work: let setParameterDbType (param: DbParameter) (qp: QueryParameter) =
match qp.ProviderDbType, compiler with
| Some dbType, :? SqlKata.Compilers.PostgresCompiler ->
let property = param.GetType().GetProperty("NpgsqlDbType")
let dbTypeSetter = property.GetSetMethod()
let value = System.Enum.Parse(property.PropertyType, dbType)
dbTypeSetter.Invoke(param, [|value|]) |> ignore
| Some dbType, :? SqlKata.Compilers.SqlServerCompiler ->
let property = param.GetType().GetProperty("SqlDbType")
let dbTypeSetter = property.GetSetMethod()
let value = System.Enum.Parse(property.PropertyType, dbType)
dbTypeSetter.Invoke(param, [|value|]) |> ignore
| _ -> ()
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, the code now looks almost as yours, just with a helper function to hide the reflection ugliness 🙂 |
||
| interface System.IDisposable with | ||
| member this.Dispose() = | ||
| conn.Dispose() | ||
|
|
@@ -44,7 +53,13 @@ type QueryContext(conn: DbConnection, compiler: SqlKata.Compilers.Compiler) = | |
| for kvp in compiledQuery.NamedBindings do | ||
| let p = cmd.CreateParameter() | ||
| p.ParameterName <- kvp.Key | ||
| p.Value <- kvp.Value | ||
|
|
||
| match kvp.Value with | ||
| | :? QueryParameter as qp -> | ||
| do setParameterDbType p qp | ||
| p.Value <- qp.Value | ||
| | _ -> | ||
| p.Value <- kvp.Value | ||
| cmd.Parameters.Add(p) |> ignore | ||
| cmd | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <TargetFramework>netstandard2.0</TargetFramework> | ||
| <TargetFramework>net5.0</TargetFramework> | ||
| <GenerateDocumentationFile>true</GenerateDocumentationFile> | ||
| <WarnOn>3390;$(WarnOn)</WarnOn> | ||
| <Version>0.530.0</Version> | ||
|
|
@@ -32,4 +32,8 @@ | |
| <PackageReference Include="SqlKata" Version="2.3.7" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\SqlHydra\SqlHydra.fsproj" /> | ||
|
||
| </ItemGroup> | ||
|
|
||
| </Project> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| module SqlHydra.DbColumnTypeAttribute | ||
|
|
||
| open System | ||
| open SqlHydra.Domain | ||
|
|
||
| [<AttributeUsage(AttributeTargets.Property | ||
| ||| AttributeTargets.Field)>] | ||
| type DbColumnTypeAttribute(columnTypeName: string, columnTypeValue: string) = | ||
| inherit Attribute() | ||
|
|
||
| member this.ColumnType: DbColumnType = | ||
| { TypeName = columnTypeName | ||
| TypeValue = columnTypeValue } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than defining a lookup function, I think that this mapping should be added as a
string optionfield on thesupportedTypeMappingsfor each of the providers (NpgsqlDataTypes.fs,SqliteDataTypes.fs, andSqlServerDataTypes.fs. Most of them can default toNone.This value can then be moved from the
Columnrecord to to theTypeMappingrecord.The
TypeMappingrecord already has aDbTypeproperty that holds theSystem.Data.DbTypeenum.Since each provider has its own more specific enumeration (i.e.
NpgsqlDbTypefor Postgres,SqlDbTypefor SQL Server -- and I don't think SQLite has a more specific enum), I suppose the new property should beProviderDbType.