Repository navigation
Expand file tree
/
Copy pathCodeStatic.fs
More file actions
173 lines (141 loc) · 5.28 KB
/
Copy pathCodeStatic.fs
File metadata and controls
173 lines (141 loc) · 5.28 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
module PgGen.CodeStatic
open System.IO
open PgGen.StringBuffer
open Common
open System
let compileTimeDbFile = "compile_time_db.txt"
let dbFileSource proj =
stringBuffer {
yield $"module {proj |> titleCase}.Db\n"
yield $"\n"
yield $"open Plough.ControlFlow\n"
yield $"open System\n"
yield $"open FSharp.Data.Npgsql\n"
yield $"open FSharp.Data.LiteralProviders\n"
yield $"open System.Transactions\n"
yield sprintf """
module AppConfig =
[<CLIMutable>]
type AppConfig =
{ ConnectionString : string
}
module Db =
let [<Literal>] defaultCommandTimeout = 600
let mutable connectionString = None
/// compile time connection string set via lims specific txt file with default value if file not found
let [<Literal>] connectionStringCompileTime = TextFile<"%s">.Text
let [<Literal>] methodTypes = MethodTypes.Task ||| MethodTypes.Sync
module TenantRls =
type TenantContext = {
TenantId : string
OrganizationId : string option
}
let private ambientTenant = new System.Threading.AsyncLocal<TenantContext option>()
let setAmbient (tenant:TenantContext) =
ambientTenant.Value <- Some tenant
let setAmbientFromValues (tenantId:string) (organizationId:string) =
let org =
if String.IsNullOrWhiteSpace organizationId then
None
else
Some organizationId
setAmbient { TenantId = tenantId; OrganizationId = org }
let clearAmbient () =
ambientTenant.Value <- None
let tryGetAmbient () =
ambientTenant.Value
let private escapeSqlLiteral (value:string) =
value.Replace("'", "''")
let buildSessionSql (tenant:TenantContext) =
let tenantId = escapeSqlLiteral tenant.TenantId
let orgId = tenant.OrganizationId |> Option.defaultValue "" |> escapeSqlLiteral
"select set_config('app.tenant_id', '" + tenantId + "', true);\n"
+ "select set_config('app.organization_id', '" + orgId + "', true);\n"
let applyToConnection (connection:Npgsql.NpgsqlConnection) (tenant:TenantContext) =
task {
use cmd = connection.CreateCommand()
cmd.CommandText <- buildSessionSql tenant
let! _ = cmd.ExecuteNonQueryAsync(Async.DefaultCancellationToken)
return ()
}
let applyAmbientToConnection (connection:Npgsql.NpgsqlConnection) =
task {
match ambientTenant.Value with
| Some tenant ->
do! applyToConnection connection tenant
| None ->
()
}
type Db<'a>() =
static member inline openConnectionAsync() =
task {
let conn = new Npgsql.NpgsqlConnection(Db.connectionString.Value)
do! conn.OpenAsync(Async.DefaultCancellationToken)
return conn
}
static member inline openConnection() =
let conn = new Npgsql.NpgsqlConnection(Db.connectionString.Value)
conn.Open()
conn
static member inline createTransactionScope isolationLevel =
new TransactionScope(TransactionScopeOption.Required,
TransactionOptions(
IsolationLevel=isolationLevel,
Timeout=TransactionManager.MaximumTimeout
),
TransactionScopeAsyncFlowOption.Enabled)
//static member inline createTransactionScope () =
// Db.createTransactionScope IsolationLevel.ReadCommitted
type Db = NpgsqlConnection<ConnectionString=Db.connectionStringCompileTime,
CollectionType=CollectionType.ResizeArray, MethodTypes=Db.methodTypes,
Prepare=true, XCtor=true, CommandTimeout=Db.defaultCommandTimeout>
""" compileTimeDbFile
}
// ------ tool file setup
let paketFile = """source https://api.nuget.org/v3/index.json
framework: net"""+dotnetVersion+"""
storage:none
nuget FSharp.Core
nuget FSharp.Data.Npgsql >= 2.0.0
nuget FSharp.Data.LiteralProviders >= 1.0.0
nuget Npgsql >= 10.0.0
nuget Plough.ControlFlow >= 1.1.0
nuget Giraffe >= 6.0.0
nuget Thoth.Json.Giraffe >= 1.2.2
nuget Plough.WebApi.Client.Dotnet >= 1.2.2
#nuget Plough.WebApi.Server >= 1.2.2
nuget Plough.WebApi.Server.Giraffe >= 1.2.2
"""
let paketReferencesFile = """FSharp.Core
Fsharp.Data.Npgsql
FSharp.Data.LiteralProviders
Npgsql
Plough.ControlFlow
Plough.WebApi.Server.Giraffe
Plough.WebApi.Client.Dotnet
"""
let dotnetToolsJson = $"{{
\"version\": 1,
\"isRoot\": true,
\"tools\": {{
\"paket\": {{
\"version\": \"{paketVersion}\",
\"commands\": [
\"paket\"
]
}}
}}
}}"
let commonFileSource proj =
stringBuffer {
yield $"module {proj |> titleCase}.Common\n"
yield $"\n"
yield $"open Plough.ControlFlow\n"
yield $"open System\n"
yield $"\n"
yield $"[<CLIMutable>]\n"
yield $"type BatchOffset = {{\n"
yield $" Offset : int option\n"
yield $" BatchSize : int option}}\n"
yield $"// Shared data structures like User definitions go here\n"
}