@@ -5,21 +5,22 @@ sqlitetype(::Type{NullType}) = "NULL"
5
5
sqlitetype (x) = " BLOB"
6
6
7
7
"""
8
- independent SQLite.Sink constructor to create a new or wrap an existing SQLite table with name `tablename `.
8
+ independent SQLite.Sink constructor to create a new or wrap an existing SQLite table with name `name `.
9
9
must provide a `Data.Schema` through the `schema` argument
10
- can optionally provide an existing SQLite table name or new name that a created SQLite table will be called through the `tablename ` argument
10
+ can optionally provide an existing SQLite table name or new name that a created SQLite table will be called through the `name ` argument
11
11
`temp=true` will create a temporary SQLite table that will be destroyed automatically when the database is closed
12
- `ifnotexists=false` will throw an error if `tablename ` already exists in `db`
12
+ `ifnotexists=false` will throw an error if `name ` already exists in `db`
13
13
"""
14
14
function Sink (db:: DB , schema:: Data.Schema ; name:: AbstractString = " julia_" * randstring (), temp:: Bool = false , ifnotexists:: Bool = true , append:: Bool = false )
15
15
rows, cols = size (schema)
16
16
temp = temp ? " TEMP" : " "
17
17
ifnotexists = ifnotexists ? " IF NOT EXISTS" : " "
18
18
columns = [string (esc_id (schema. header[i]), ' ' , sqlitetype (schema. types[i])) for i = 1 : cols]
19
19
SQLite. execute! (db, " CREATE $temp TABLE $ifnotexists $(esc_id (name)) ($(join (columns, ' ,' )) )" )
20
+ ! append && execute! (db, " delete from $(esc_id (name)) " )
20
21
params = chop (repeat (" ?," , cols))
21
22
stmt = SQLite. Stmt (db, " INSERT INTO $(esc_id (name)) VALUES ($params )" )
22
- return Sink (schema, db, name, stmt)
23
+ return Sink (schema, db, name, stmt, " " )
23
24
end
24
25
25
26
" constructs a new SQLite.Sink from the given `SQLite.Source`; uses `source` schema to create the SQLite table"
35
36
Data. streamtypes {T<:SQLite.Sink} (:: Type{T} ) = [Data. Field]
36
37
37
38
function Sink {T} (source, :: Type{T} , append:: Bool , db:: DB , name:: AbstractString = " julia_" * randstring ())
38
- sink = Sink (db, Data. schema (source); name= name)
39
- ! append && execute! (db, " delete from $name " )
39
+ sink = Sink (db, Data. schema (source); name= name, append= append)
40
40
return sink
41
41
end
42
42
function Sink {T} (sink, source, :: Type{T} , append:: Bool )
43
- ! append && execute! (sink. db, " delete from $(sink. tablename) " )
43
+ ! append && execute! (sink. db, " delete from $(esc_id ( sink. tablename) ) " )
44
44
return sink
45
45
end
46
46
@@ -64,33 +64,35 @@ if isdefined(:isna)
64
64
else
65
65
getbind! {T} (val:: T , col, stmt) = SQLite. bind! (stmt, col, val)
66
66
end
67
- function getfield! {T} (source, :: Type{T} , stmt, row, col)
68
- val = Data. getfield (source, T, row, col)
69
- getbind! (val, col, stmt)
67
+
68
+ function Data. open! (sink:: SQLite.Sink , source)
69
+ execute! (sink. db," PRAGMA synchronous = OFF;" )
70
+ sink. transaction = string (" SQLITE" ,randstring (10 ))
71
+ transaction (sink. db, sink. transaction)
72
+ return nothing
70
73
end
71
- # stream the data in `dt` into the SQLite table represented by `sink`
72
- function Data. stream! (source, :: Type{Data.Field} , sink:: SQLite.Sink , append:: Bool )
73
- ! append && execute! (sink. db, " delete from $(sink. tablename) " )
74
- rows, cols = size (source)
75
- Data. isdone (source, 1 , 1 ) && return sink
76
- types = Data. types (source)
77
- handle = sink. stmt. handle
78
- transaction (sink. db) do
79
- row = 1
80
- while true
81
- for col = 1 : cols
82
- @inbounds T = types[col]
83
- @inbounds getfield! (source, T, sink. stmt, row, col)
84
- end
85
- SQLite. sqlite3_step (handle)
86
- SQLite. sqlite3_reset (handle)
87
- row += 1
88
- Data. isdone (source, row, cols) && break
89
- end
90
- Data. setrows! (source, row - 1 )
74
+
75
+ function Data. streamfield! {T} (sink:: SQLite.Sink , source, :: Type{T} , row, col, cols)
76
+ val = Data. getfield (source, T, row ,col)
77
+ getbind! (val, col, sink. stmt)
78
+ if col == cols
79
+ SQLite. sqlite3_step (sink. stmt. handle)
80
+ SQLite. sqlite3_reset (sink. stmt. handle)
91
81
end
92
- SQLite. execute! (sink. db," ANALYZE $(esc_id (sink. tablename)) " )
93
- return sink
82
+ return nothing
83
+ end
84
+
85
+ function Data. cleanup! (sink:: SQLite.Sink )
86
+ rollback (sink. db, sink. transaction)
87
+ execute! (sink. db, " PRAGMA synchronous = ON;" )
88
+ return nothing
89
+ end
90
+
91
+ function Data. close! (sink:: SQLite.Sink )
92
+ commit (sink. db, sink. transaction)
93
+ execute! (sink. db, " PRAGMA synchronous = ON;" )
94
+ SQLite. execute! (sink. db, " ANALYZE $(esc_id (sink. tablename)) " )
95
+ return nothing
94
96
end
95
97
96
98
"""
@@ -105,17 +107,20 @@ function load{T}(db, name, ::Type{T}, args...;
105
107
append:: Bool = false )
106
108
source = T (args... )
107
109
schema = Data. schema (source)
108
- sink = Sink (db, schema; name= name, temp= temp, ifnotexists= ifnotexists)
109
- return Data. stream! (source, sink, append)
110
+ sink = Sink (db, schema; name= name, temp= temp, ifnotexists= ifnotexists, append= append)
111
+ Data. stream! (source, sink, append)
112
+ Data. close! (sink)
113
+ return sink
110
114
end
111
115
function load {T} (db, name, source:: T ;
112
116
temp:: Bool = false ,
113
117
ifnotexists:: Bool = true ,
114
118
append:: Bool = false )
115
- schema = Data. schema (source)
116
- sink = Sink (db, schema; name= name, temp= temp, ifnotexists= ifnotexists)
117
- return Data. stream! (source, sink, append)
119
+ sink = Sink (db, Data. schema (source); name= name, temp= temp, ifnotexists= ifnotexists, append= append)
120
+ Data. stream! (source, sink, append)
121
+ Data. close! (sink)
122
+ return sink
118
123
end
119
124
120
- load {T} (sink:: Sink , :: Type{T} , args... ; append:: Bool = false ) = Data. stream! (T (args... ), sink, append)
121
- load (sink:: Sink , source; append:: Bool = false ) = Data. stream! (source, sink, append)
125
+ load {T} (sink:: Sink , :: Type{T} , args... ; append:: Bool = false ) = (sink = Data. stream! (T (args... ), sink, append); Data . close! (sink); return sink )
126
+ load (sink:: Sink , source; append:: Bool = false ) = (sink = Data. stream! (source, sink, append); Data . close! (sink); return sink )
0 commit comments