Skip to content

Commit c43d73f

Browse files
committed
Add Rezoom.SQL.Raw module to help build dynamic SQL commands.
1 parent 11f0855 commit c43d73f

3 files changed

Lines changed: 60 additions & 2 deletions

File tree

src/Rezoom.SQL.Mapping/Raw.fs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/// Provides helpers for building raw SQL commands and parameters.
2+
/// This stuff does *NOT* go through RZSQL parsing/typechecking/translation.
3+
/// It should be a last resort for when you absolutely can't accomplish what you're doing statically.
4+
module Rezoom.SQL.Raw
5+
open System
6+
open System.Data
7+
open Rezoom.SQL.Mapping
8+
open System.Collections.Generic
9+
10+
let sql text = CommandText text
11+
12+
let argOfType dbType o =
13+
InlineParameter (dbType, o)
14+
15+
let private typeMap =
16+
[| typeof<byte>, DbType.Byte
17+
typeof<sbyte>, DbType.SByte
18+
typeof<int16>, DbType.Int16
19+
typeof<uint16>, DbType.UInt16
20+
typeof<int>, DbType.Int32
21+
typeof<uint32>, DbType.UInt32
22+
typeof<int64>, DbType.Int64
23+
typeof<uint64>, DbType.UInt64
24+
typeof<string>, DbType.String
25+
typeof<double>, DbType.Double
26+
typeof<single>, DbType.Single
27+
typeof<bool>, DbType.Boolean
28+
typeof<Guid>, DbType.Guid
29+
typeof<decimal>, DbType.Decimal
30+
typeof<DateTime>, DbType.DateTime
31+
typeof<DateTimeOffset>, DbType.DateTimeOffset
32+
|] |> dict
33+
34+
let private guessDbType (ty : Type) =
35+
let succ, found = typeMap.TryGetValue(ty)
36+
if succ then found else DbType.Object
37+
38+
let arg (o : obj) =
39+
let dbType =
40+
if isNull o then DbType.Object
41+
else guessDbType (o.GetType())
42+
argOfType dbType o
43+
44+
let connectionDynamicCommand<'row> connectionName (sql : CommandFragment array) =
45+
let cmdData =
46+
{ ConnectionName = connectionName // should match the one in rzsql.json/App.config
47+
Fragments = sql
48+
Identity = ""
49+
DependencyMask = Rezoom.BitMask.Full
50+
InvalidationMask = Rezoom.BitMask.Full
51+
Cacheable = false
52+
ResultSetCount = None // not statically known
53+
}
54+
CommandConstructor.Command1<'row IReadOnlyList>(cmdData, [||])
55+
56+
let dynamicCommand<'row> (sql : CommandFragment array) =
57+
connectionDynamicCommand<'row> "rzsql" sql

src/Rezoom.SQL.Mapping/Rezoom.SQL.Mapping.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
<Compile Include="IScalar.fs" />
7777
<Compile Include="CommandParts.fs" />
7878
<Compile Include="Command.fs" />
79+
<Compile Include="Raw.fs" />
7980
<Compile Include="CommandBatch.fs" />
8081
<Compile Include="ConnectionProvider.fs" />
8182
<Compile Include="ConnectionContext.fs" />

src/TypeProviderUsers/TypeProviderUser.SQLite/TestSelects.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ let ``replay works`` () =
116116
()
117117
else failwith "not equal"
118118

119-
open Rezoom.SQL.Mapping
119+
open Rezoom.SQL.Raw
120120
open System.Data
121121

122122
type RawSQLQuery = SQL<"""
@@ -126,7 +126,7 @@ type RawSQLQuery = SQL<"""
126126
[<Test>]
127127
let ``test raw sql parameter`` () =
128128
let results =
129-
RawSQLQuery.Command(whereClause = [| CommandText "1="; InlineParameter(DbType.Int32, 1) |]) |> runOnTestData
129+
RawSQLQuery.Command(whereClause = [| sql "1="; arg 1 |]) |> runOnTestData
130130
for result in results do
131131
printfn "%A" result.Email
132132

0 commit comments

Comments
 (0)