1
1
# Database structure.
2
2
3
+ const SQLMetadata = Base. ImmutableDict{Symbol, Any}
4
+
5
+ _metadata (:: Nothing ) =
6
+ SQLMetadata ()
7
+
8
+ _metadata (dict:: SQLMetadata ) =
9
+ dict
10
+
11
+ _metadata (dict:: SQLMetadata , kvs... ) =
12
+ Base. ImmutableDict (dict, kvs... )
13
+
14
+ _metadata (other) =
15
+ _metadata (SQLMetadata (), pairs (other)... )
16
+
3
17
"""
4
- SQLColumn(; name)
5
- SQLColumn(name)
18
+ SQLColumn(; name, metadata = nothing )
19
+ SQLColumn(name; metadata = nothing )
6
20
7
- `SQLColumn` represents a column of a database table .
21
+ `SQLColumn` represents a column with the given `name` and optional `metadata` .
8
22
"""
9
23
struct SQLColumn
10
24
name:: Symbol
11
- metadata:: Union{Nothing, Dict{Symbol, Any}}
25
+ metadata:: SQLMetadata
12
26
13
27
function SQLColumn (; name:: Union{Symbol, AbstractString} , metadata = nothing )
14
- new (Symbol (name), metadata)
28
+ new (Symbol (name), _metadata ( metadata) )
15
29
end
16
30
end
17
31
@@ -26,9 +40,8 @@ Base.show(io::IO, ::MIME"text/plain", col::SQLColumn) =
26
40
27
41
function PrettyPrinting. quoteof (col:: SQLColumn ; limit:: Bool = false )
28
42
ex = Expr (:call , nameof (SQLColumn), QuoteNode (col. name))
29
- m = col. metadata
30
- if m != = nothing && ! isempty (m)
31
- push! (ex. args, Expr (:kw , :metadata , limit ? :… : quoteof (m)))
43
+ if ! isempty (col. metadata)
44
+ push! (ex. args, Expr (:kw , :metadata , limit ? :… : quoteof (reverse! (collect (col. metadata)))))
32
45
end
33
46
ex
34
47
end
@@ -55,35 +68,36 @@ _column_entry((n, c)::Pair{<:Union{Symbol, AbstractString}, SQLColumn}) =
55
68
Symbol (n) => c
56
69
57
70
"""
58
- SQLTable(; qualifiers = [], name, columns)
59
- SQLTable(name; qualifiers = [], columns)
60
- SQLTable(name, columns...; qualifiers = [])
71
+ SQLTable(; qualifiers = [], name, columns, metadata = nothing )
72
+ SQLTable(name; qualifiers = [], columns, metadata = nothing )
73
+ SQLTable(name, columns...; qualifiers = [], metadata = nothing )
61
74
62
75
The structure of a SQL table or a table-like entity (`TEMP TABLE`, `VIEW`, etc)
63
76
for use as a reference in assembling SQL queries.
64
77
65
- The `SQLTable` constructor expects the table `name`, an ordered dictionary
66
- `columns` that maps names to columns, and, optionally, a vector containing
67
- the name of the table schema and other `qualifiers`. A name can be a `Symbol`
68
- or a `String`.
78
+ The `SQLTable` constructor expects the table `name`, an optional vector
79
+ containing the table schema and other `qualifiers`, an ordered dictionary
80
+ `columns` that maps names to columns, and an optional `metadata`.
69
81
70
82
# Examples
71
83
72
84
```jldoctest
73
85
julia> person = SQLTable(qualifiers = ["public"],
74
86
name = "person",
75
- columns = ["person_id", "year_of_birth"])
87
+ columns = ["person_id", "year_of_birth"],
88
+ metadata = (; is_view = false))
76
89
SQLTable(qualifiers = [:public],
77
90
:person,
78
91
SQLColumn(:person_id),
79
- SQLColumn(:year_of_birth))
92
+ SQLColumn(:year_of_birth),
93
+ metadata = [:is_view => false])
80
94
```
81
95
"""
82
96
struct SQLTable <: AbstractDict{Symbol, SQLColumn}
83
97
qualifiers:: Vector{Symbol}
84
98
name:: Symbol
85
99
columns:: OrderedDict{Symbol, SQLColumn}
86
- metadata:: Union{Nothing, Dict{Symbol, Any}}
100
+ metadata:: SQLMetadata
87
101
88
102
function SQLTable (;
89
103
qualifiers:: AbstractVector{<:Union{Symbol, AbstractString}} = Symbol[],
@@ -96,7 +110,7 @@ struct SQLTable <: AbstractDict{Symbol, SQLColumn}
96
110
qualifiers
97
111
name = Symbol (name)
98
112
columns = _column_map (columns)
99
- new (qualifiers, name, columns, metadata)
113
+ new (qualifiers, name, columns, _metadata ( metadata) )
100
114
end
101
115
end
102
116
@@ -126,9 +140,8 @@ function PrettyPrinting.quoteof(tbl::SQLTable; limit::Bool = false)
126
140
end
127
141
push! (ex. args, arg)
128
142
end
129
- m = tbl. metadata
130
- if m != = nothing && ! isempty (m)
131
- push! (ex. args, Expr (:kw , :metadata , quoteof (m)))
143
+ if ! isempty (tbl. metadata)
144
+ push! (ex. args, Expr (:kw , :metadata , quoteof (reverse! (collect (tbl. metadata)))))
132
145
end
133
146
else
134
147
push! (ex. args, :… )
@@ -171,11 +184,13 @@ _table_entry((n, t)::Pair{<:Union{Symbol, AbstractString}, SQLTable}) =
171
184
"""
172
185
SQLCatalog(; tables = Dict{Symbol, SQLTable}(),
173
186
dialect = :default,
174
- cache = $default_cache_maxsize )
175
- SQLCatalog(tables...; dialect = :default, cache = $default_cache_maxsize )
187
+ cache = $default_cache_maxsize ,
188
+ metadata = nothing)
189
+ SQLCatalog(tables...;
190
+ dialect = :default, cache = $default_cache_maxsize , metadata = nothing)
176
191
177
192
`SQLCatalog` encapsulates available database `tables`, the target SQL `dialect`,
178
- and a `cache` of serialized queries.
193
+ a `cache` of serialized queries, and an optional `metadata` .
179
194
180
195
Parameter `tables` is either a dictionary or a vector of [`SQLTable`](@ref)
181
196
objects, where the vector will be converted to a dictionary with
@@ -210,14 +225,14 @@ struct SQLCatalog <: AbstractDict{Symbol, SQLTable}
210
225
tables:: Dict{Symbol, SQLTable}
211
226
dialect:: SQLDialect
212
227
cache:: Any # Union{AbstractDict{SQLNode, SQLString}, Nothing}
213
- metadata:: Union{Nothing, Dict{Symbol, Any}}
228
+ metadata:: SQLMetadata
214
229
215
230
function SQLCatalog (; tables = Dict {Symbol, SQLTable} (), dialect = :default , cache = default_cache_maxsize, metadata = nothing )
216
231
table_map = _table_map (tables)
217
232
if cache isa Number
218
233
cache = LRU {SQLNode, SQLString} (maxsize = cache)
219
234
end
220
- new (table_map, dialect, cache, metadata)
235
+ new (table_map, dialect, cache, _metadata ( metadata) )
221
236
end
222
237
end
223
238
@@ -245,9 +260,8 @@ function PrettyPrinting.quoteof(c::SQLCatalog)
245
260
else
246
261
push! (ex. args, Expr (:kw , :cache , Expr (:call , typeof (cache))))
247
262
end
248
- m = c. metadata
249
- if m != = nothing && ! isempty (m)
250
- push! (ex. args, Expr (:kw , :metadata , quoteof (m)))
263
+ if ! isempty (c. metadata)
264
+ push! (ex. args, Expr (:kw , :metadata , quoteof (reverse! (collect (c. metadata)))))
251
265
end
252
266
ex
253
267
end
@@ -271,9 +285,8 @@ function Base.show(io::IO, c::SQLCatalog)
271
285
else
272
286
print (io, " , cache = " , typeof (cache), " ()" )
273
287
end
274
- m = c. metadata
275
- if m != = nothing && ! isempty (m)
276
- print (io, " , metadata = Dict(…)" )
288
+ if ! isempty (c. metadata)
289
+ print (io, " , metadata = …" )
277
290
end
278
291
print (io, ' )' )
279
292
nothing
0 commit comments