-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBuild.fs
169 lines (147 loc) · 5.34 KB
/
Build.fs
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
module PgGen.Build
open Common
let defaultOwner = "read_write"
let col (name:string) (cType:ColumnType) (modList:ColumnMatters list) =
let hasMod (x:ColumnMatters) = modList |> List.contains x
let comment =
match modList |> List.filter (fun a -> match a with | CComment _ -> true | _ -> false) with
| [CComment c] -> Some c
| [] -> None
| x -> failwithf "Multiple comments for column {name} {x}"
ColumnItem
{ CName = name
CType = cType
Nullable = hasMod Nullable
Array = hasMod Array
Comment = comment
}
let table (name:string) (tableAttr:TableAttr list) (body:TableBodyItem list) =
let comment =
match tableAttr |> List.filter (fun a -> match a with | Comment _ -> true | _ -> false) with
| [Comment c] -> Some c
| [] -> None
| x -> failwithf "Multiple comments for table {name} {x}"
TableItem
{ TName = name
Attributes = tableAttr
Cols = [ for b in body do
match b with
| ColumnItem c ->
c
| _ -> ()
]
Uniques = [ for b in body do
match b with
| Unique u -> u
| _ -> () ]
FRefs = [ for b in body do
match b with
| ForeignRef f -> f
| _ -> ()
]
ERefs = [ for e in body do
match e with
| EnumRef e -> e
| _ -> ()
]
Comment = comment
PKey =
body
|> List.choose (fun x -> match x with | TableBodyItem.PKey x -> Some x | _ -> None)
|> List.tryHead
}
let schema (name:string) (schemaAttr:SchemaAttr list) (body:SchemaBodyItem list) =
let comment =
schemaAttr
|> List.tryFind (fun a -> match a with | SComment _ -> true | _ -> false)
|> Option.map (fun c -> match c with | SComment c -> c | _ -> failwithf "impossible")
let enums = [ for b in body do
match b with
| PEnum e -> e
| _ -> ()
]
let tables = [ for t in body do
match t with
| TableItem t -> yield t
| _ -> ()]
SchemaItem {
SName = name
Tables = tables
Comment = comment
Enums = enums
}
let db (name:string) (dbAttr:DBAttr list) (body:DBBodyItem list) =
let comment =
match dbAttr |> List.filter (fun a -> match a with | DComment _ -> true | _ -> false) with
| [DComment c] -> Some c
| [] -> None
| x -> failwithf $"Multiple comments for db {name} {x}"
{ DName = name
Schemas = [ for s in body do
match s with
| SchemaItem s -> s ]
Owner =
match (dbAttr
|> List.tryFind (fun a -> match a with | Owner o -> true | _ -> false) ) with
| Some(Owner o) -> o
| _ -> defaultOwner
Comment = comment
}
let unique (cols:string list) =
Unique {
Cols = cols }
let frefId (reference:string) (attrs:FRefAttr list) =
let name =
match List.filter (fun a -> match a with | FName n -> true | _ -> false) attrs with
| [FName n] -> Some n
| [] -> None
| x -> failwithf $"frefId: expected one name, got multiple {x}"
let schema, table =
match reference with
| Regex @"(.+)\.(.+)" [schema ; table] -> Some schema,table
| s -> None, s
ForeignRef
{ FromTable = None
FromSchema = None
FromCols = [name |> Option.defaultValue $"id_{table}"]
ToTable = table
ToSchema = schema
ToCols = ["id"]
Generate = true
Name = name
IsNullable = attrs |> List.exists (fun a -> match a with | FNullable -> true | _ -> false)
}
let enumDef (name:string) (attrs:EAttr list) =
let comment =
match attrs |> List.filter (fun a -> match a with | EComment _ -> true | _ -> false) with
| [EComment c] -> Some c
| [] -> None
| x -> failwithf $"Multiple comments for enum {name} {x}"
PEnum
{ EName = name
EValues = [ for a in attrs do
match a with
| Member v -> yield v
| _ ->()
]
EComment = comment
}
let enum (name:string) (attrs:EnumRefAttr list) =
let schema, enum =
match name with
| Regex @"(.+)\.(.+)" [schema ; enum] -> Some schema,enum
| s -> None, s
let name =
match attrs |> List.filter (fun a -> match a with | EName n -> true | _ -> false) with
| [EName n] -> Some n
| [] -> None
| x -> failwithf $"enum: expected one name, got multiple {x}"
EnumRef
{ EName = enum
ESchema = schema
Name = name
IsNullable = attrs |> List.exists (fun a -> match a with | ENullable -> true | _ -> false)
Generate = true // only option right now
}
let pKey (cols:string list) =
PKey { Cols = cols }