-
Notifications
You must be signed in to change notification settings - Fork 189
Expand file tree
/
Copy pathBuilder.hs
More file actions
234 lines (187 loc) · 10.1 KB
/
Builder.hs
File metadata and controls
234 lines (187 loc) · 10.1 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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE CPP #-}
-- | DDL syntax instances for 'SqlSyntaxBuilder'
module Database.Beam.Migrate.SQL.Builder where
import Database.Beam.Backend.SQL
import Database.Beam.Backend.SQL.Builder
import Database.Beam.Migrate.SQL
import Database.Beam.Migrate.Serialization
import Control.Applicative
import Data.ByteString.Builder (Builder, byteString, toLazyByteString)
import qualified Data.ByteString.Lazy.Char8 as BCL
import qualified Data.List.NonEmpty as NE
-- | Options for @CREATE TABLE@. Given as a separate ADT because the options may
-- go in different places syntactically.
--
-- You never really need to use this type directly.
data SqlSyntaxBuilderCreateTableOptions
= SqlSyntaxBuilderCreateTableOptions
SqlSyntaxBuilder
SqlSyntaxBuilder
deriving Eq
instance IsSql92DdlSchemaCommandSyntax SqlSyntaxBuilder where
type Sql92DdlCommandCreateSchemaSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92DdlCommandDropSchemaSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
createSchemaCmd = id
dropSchemaCmd = id
instance IsSql92DdlCommandSyntax SqlSyntaxBuilder where
type Sql92DdlCommandCreateTableSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92DdlCommandDropTableSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92DdlCommandAlterTableSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
createTableCmd = id
alterTableCmd = id
dropTableCmd = id
instance IsSql92DropTableSyntax SqlSyntaxBuilder where
type Sql92DropTableTableNameSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
dropTableSyntax tblNm =
SqlSyntaxBuilder $
byteString "DROP TABLE " <> buildSql tblNm
instance IsSql92AlterTableSyntax SqlSyntaxBuilder where
type Sql92AlterTableTableNameSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92AlterTableAlterTableActionSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
alterTableSyntax tblNm action =
SqlSyntaxBuilder $
byteString "ALTER TABLE " <> buildSql tblNm <> byteString " " <> buildSql action
instance IsSql92AlterTableActionSyntax SqlSyntaxBuilder where
type Sql92AlterTableAlterColumnActionSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92AlterTableColumnSchemaSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
alterColumnSyntax colNm action =
SqlSyntaxBuilder $
byteString "ALTER COLUMN " <> quoteSql colNm <> byteString " " <> buildSql action
addColumnSyntax colNm colSchema =
SqlSyntaxBuilder $
byteString "ADD COLUMN " <> quoteSql colNm <> byteString " " <> buildSql colSchema
dropColumnSyntax colNm =
SqlSyntaxBuilder $
byteString "DROP COLUMN " <> quoteSql colNm
renameColumnToSyntax oldNm newNm =
SqlSyntaxBuilder $
byteString "RENAME COLUMN " <> quoteSql oldNm <> " TO " <> quoteSql newNm
renameTableToSyntax newNm =
SqlSyntaxBuilder $
byteString "RENAME TO " <> quoteSql newNm
instance IsSql92AlterColumnActionSyntax SqlSyntaxBuilder where
setNotNullSyntax = SqlSyntaxBuilder (byteString "SET NOT NULL")
setNullSyntax = SqlSyntaxBuilder (byteString "DROP NOT NULL")
instance IsSql92CreateSchemaSyntax SqlSyntaxBuilder where
type Sql92CreateSchemaSchemaNameSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
createSchemaSyntax schName =
SqlSyntaxBuilder $
byteString "CREATE SCHEMA " <> buildSql schName
instance IsSql92DropSchemaSyntax SqlSyntaxBuilder where
type Sql92DropSchemaSchemaNameSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
dropSchemaSyntax schName =
SqlSyntaxBuilder $
byteString "DROP SCHEMA " <> buildSql schName
instance IsSql92CreateTableSyntax SqlSyntaxBuilder where
type Sql92CreateTableTableNameSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92CreateTableColumnSchemaSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92CreateTableTableConstraintSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92CreateTableOptionsSyntax SqlSyntaxBuilder = SqlSyntaxBuilderCreateTableOptions
createTableSyntax tableOptions tblName fieldSchemas constraints =
SqlSyntaxBuilder $
byteString "CREATE " <>
maybe mempty (\b -> buildSql b <> byteString " ") beforeOptions <>
byteString " TABLE " <>
buildSql tblName <>
byteString "(" <>
buildSepBy (byteString ", ")
(map (\(nm, schema) -> quoteSql nm <> byteString " " <> buildSql schema) fieldSchemas <>
map buildSql constraints) <>
byteString ")" <>
maybe mempty (\a -> buildSql a <> byteString " ") afterOptions
where
(beforeOptions, afterOptions) =
case tableOptions of
Just (SqlSyntaxBuilderCreateTableOptions b a) -> (Just b, Just a)
Nothing -> (Nothing, Nothing)
instance IsSql92TableConstraintSyntax SqlSyntaxBuilder where
primaryKeyConstraintSyntax fs =
SqlSyntaxBuilder $
byteString "PRIMARY KEY(" <> buildSepBy (byteString ", ") (map quoteSql $ NE.toList fs) <> byteString ")"
-- | Some backends use this to represent their constraint attributes. Does not
-- need to be used in practice.
data ConstraintAttributeTiming = InitiallyDeferred | InitiallyImmediate
deriving (Show, Eq, Ord, Enum, Bounded)
-- | Valid 'IsSql92ConstraintAttributesSyntax' shared among some backends.
data SqlConstraintAttributesBuilder
= SqlConstraintAttributesBuilder
{ _sqlConstraintAttributeTiming :: Maybe ConstraintAttributeTiming
, _sqlConstraintAttributeDeferrable :: Maybe Bool }
deriving (Show, Eq)
instance Semigroup SqlConstraintAttributesBuilder where
a <> b =
SqlConstraintAttributesBuilder
(_sqlConstraintAttributeTiming b <|> _sqlConstraintAttributeTiming a)
(_sqlConstraintAttributeDeferrable b <|> _sqlConstraintAttributeDeferrable a)
instance Monoid SqlConstraintAttributesBuilder where
mempty = SqlConstraintAttributesBuilder Nothing Nothing
-- | Convert a 'SqlConstraintAttributesBuilder' to its @SQL92@ representation in
-- the returned 'ByteString' 'Builder'.
fromSqlConstraintAttributes :: SqlConstraintAttributesBuilder -> Builder
fromSqlConstraintAttributes (SqlConstraintAttributesBuilder timing deferrable) =
maybe mempty timingBuilder timing <> maybe mempty deferrableBuilder deferrable
where timingBuilder InitiallyDeferred = byteString "INITIALLY DEFERRED"
timingBuilder InitiallyImmediate = byteString "INITIALLY IMMEDIATE"
deferrableBuilder False = byteString "NOT DEFERRABLE"
deferrableBuilder True = byteString "DEFERRABLE"
-- | Serialize a 'SqlConstraintAttributesBuilder'
sqlConstraintAttributesSerialized :: SqlConstraintAttributesBuilder -> BeamSerializedConstraintAttributes
sqlConstraintAttributesSerialized (SqlConstraintAttributesBuilder timing deferrable) =
mconcat [ maybe mempty serializeTiming timing
, maybe mempty serializeDeferrable deferrable ]
where
serializeTiming InitiallyDeferred = initiallyDeferredAttributeSyntax
serializeTiming InitiallyImmediate = initiallyImmediateAttributeSyntax
serializeDeferrable True = deferrableAttributeSyntax
serializeDeferrable False = notDeferrableAttributeSyntax
instance IsSql92ConstraintAttributesSyntax SqlConstraintAttributesBuilder where
initiallyDeferredAttributeSyntax = SqlConstraintAttributesBuilder (Just InitiallyDeferred) Nothing
initiallyImmediateAttributeSyntax = SqlConstraintAttributesBuilder (Just InitiallyImmediate) Nothing
deferrableAttributeSyntax = SqlConstraintAttributesBuilder Nothing (Just True)
notDeferrableAttributeSyntax = SqlConstraintAttributesBuilder Nothing (Just False)
instance IsSql92ColumnSchemaSyntax SqlSyntaxBuilder where
type Sql92ColumnSchemaColumnConstraintDefinitionSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92ColumnSchemaColumnTypeSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92ColumnSchemaExpressionSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
columnSchemaSyntax type_ default_ constraints collation =
SqlSyntaxBuilder $
buildSql type_ <>
maybe mempty (\d -> byteString " DEFAULT " <> buildSql d) default_ <>
(case constraints of
[] -> mempty
_ -> foldMap (\c -> byteString " " <> buildSql c) constraints) <>
maybe mempty (\nm -> byteString " COLLATE " <> quoteSql nm) collation
instance IsSql92ColumnConstraintDefinitionSyntax SqlSyntaxBuilder where
type Sql92ColumnConstraintDefinitionConstraintSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92ColumnConstraintDefinitionAttributesSyntax SqlSyntaxBuilder = SqlConstraintAttributesBuilder
constraintDefinitionSyntax nm c attrs =
SqlSyntaxBuilder $
maybe mempty (\nm' -> byteString "CONSTRAINT " <> quoteSql nm' <> byteString " ") nm <>
buildSql c <>
maybe mempty fromSqlConstraintAttributes attrs
instance IsSql92ColumnConstraintSyntax SqlSyntaxBuilder where
type Sql92ColumnConstraintMatchTypeSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92ColumnConstraintReferentialActionSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
type Sql92ColumnConstraintExpressionSyntax SqlSyntaxBuilder = SqlSyntaxBuilder
notNullConstraintSyntax = SqlSyntaxBuilder (byteString "NOT NULL")
uniqueColumnConstraintSyntax = SqlSyntaxBuilder (byteString "UNIQUE")
primaryKeyColumnConstraintSyntax = SqlSyntaxBuilder (byteString "PRIMARY KEY")
checkColumnConstraintSyntax e = SqlSyntaxBuilder ("CHECK (" <> buildSql e <> ")")
referencesConstraintSyntax tbl fields match onUpdate onDelete =
SqlSyntaxBuilder $
"REFERENCES " <> quoteSql tbl <> "(" <>
buildSepBy ", " (map quoteSql fields) <> ")" <>
maybe mempty (\m -> " " <> buildSql m) match <>
maybe mempty (\a -> " ON UPDATE " <> buildSql a) onUpdate <>
maybe mempty (\a -> " ON DELETE " <> buildSql a) onDelete
instance IsSql92MatchTypeSyntax SqlSyntaxBuilder where
fullMatchSyntax = SqlSyntaxBuilder "FULL"
partialMatchSyntax = SqlSyntaxBuilder "PARTIAL"
instance IsSql92ReferentialActionSyntax SqlSyntaxBuilder where
referentialActionCascadeSyntax = SqlSyntaxBuilder "CASCADE"
referentialActionNoActionSyntax = SqlSyntaxBuilder "NO ACTION"
referentialActionSetDefaultSyntax = SqlSyntaxBuilder "SET DEFAULT"
referentialActionSetNullSyntax = SqlSyntaxBuilder "SET NULL"
instance Sql92DisplaySyntax SqlSyntaxBuilder where
displaySyntax = BCL.unpack . toLazyByteString . buildSql