@@ -2,18 +2,27 @@ using Tables
2
2
3
3
sym (ptr) = ccall (:jl_symbol , Ref{Symbol}, (Ptr{UInt8},), ptr)
4
4
5
- struct Query{NT}
5
+ struct Query
6
6
stmt:: Stmt
7
7
status:: Base.RefValue{Cint}
8
+ names:: Vector{Symbol}
9
+ types:: Vector{Type}
10
+ lookup:: Dict{Symbol, Int}
8
11
end
9
12
10
- Tables. istable (:: Type{<:Query} ) = true
11
- Tables. rowaccess (:: Type{<:Query} ) = true
13
+ struct Row
14
+ q:: Query
15
+ end
16
+
17
+ getquery (r:: Row ) = getfield (r, :q )
18
+
19
+ Tables. istable (:: Type{Query} ) = true
20
+ Tables. rowaccess (:: Type{Query} ) = true
12
21
Tables. rows (q:: Query ) = q
13
- Tables. schema (q:: Query{NamedTuple{names, types}} ) where {names, types} = Tables. Schema (names, types)
22
+ Tables. schema (q:: Query ) = Tables. Schema (q . names, q . types)
14
23
15
- Base. IteratorSize (:: Type{<: Query} ) = Base. SizeUnknown ()
16
- Base. eltype (q:: Query{NT} ) where {NT} = NT
24
+ Base. IteratorSize (:: Type{Query} ) = Base. SizeUnknown ()
25
+ Base. eltype (q:: Query ) = Row
17
26
18
27
function reset! (q:: Query )
19
28
sqlite3_reset (q. stmt. handle)
@@ -39,26 +48,29 @@ function getvalue(q::Query, col::Int, ::Type{T}) where {T}
39
48
end
40
49
end
41
50
42
- function generate_namedtuple (:: Type{NamedTuple{names, types}} , q) where {names, types}
43
- if @generated
44
- vals = Tuple (:(getvalue (q, $ i, $ (fieldtype (types, i)))) for i = 1 : fieldcount (types))
45
- return :(NamedTuple {names, types} (($ (vals... ),)))
46
- else
47
- return NamedTuple {names, types} (Tuple (getvalue (q, i, fieldtype (types, i)) for i = 1 : fieldcount (types)))
48
- end
51
+ Base. getindex (r:: Row , col:: Int ) = getvalue (getquery (r), col, getquery (r). types[col])
52
+
53
+ function Base. getindex (r:: Row , col:: Symbol )
54
+ q = getquery (r)
55
+ i = q. lookup[col]
56
+ return getvalue (q, i, q. types[i])
57
+ end
58
+
59
+ function Base. getproperty (r:: Row , col:: Symbol )
60
+ q = getquery (r)
61
+ i = q. lookup[col]
62
+ return getvalue (q, i, q. types[i])
49
63
end
50
64
51
- function Base. iterate (q:: Query{NT} ) where {NT}
65
+ function Base. iterate (q:: Query )
52
66
done (q) && return nothing
53
- nt = generate_namedtuple (NT, q)
54
- return nt, nothing
67
+ return Row (q), nothing
55
68
end
56
69
57
- function Base. iterate (q:: Query{NT} , :: Nothing ) where {NT}
70
+ function Base. iterate (q:: Query , :: Nothing )
58
71
q. status[] = sqlite3_step (q. stmt. handle)
59
72
done (q) && return nothing
60
- nt = generate_namedtuple (NT, q)
61
- return nt, nothing
73
+ return Row (q), nothing
62
74
end
63
75
64
76
"""
@@ -93,7 +105,7 @@ function Query(db::DB, sql::AbstractString; values=[], stricttypes::Bool=true, n
93
105
types[i] = stricttypes ? juliatype (stmt. handle, i) : Any
94
106
end
95
107
end
96
- return Query {NamedTuple{Tuple(header ), Tuple{ types...}}} (stmt, Ref (status ))
108
+ return Query (stmt, Ref (status ), header, types, Dict (x => i for (i, x) in enumerate (header) ))
97
109
end
98
110
99
111
# as a sink
0 commit comments