@@ -119,6 +119,20 @@ function createtable!(db::DB, nm::AbstractString, ::Tables.Schema{names, types};
119
119
return execute (db, " CREATE $temp TABLE $ifnotexists $nm ($(join (columns, ' ,' )) )" )
120
120
end
121
121
122
+ struct TableInfo
123
+ exists:: Bool
124
+ names:: Vector{String}
125
+ end
126
+ function tableinfo (db:: DB , name:: AbstractString )
127
+ table_info = Tables. columntable (DBInterface. execute (db, " pragma table_info($name )" ))
128
+ exists = table_info != = NamedTuple ()
129
+ if exists
130
+ return TableInfo (exists, table_info. name)
131
+ else
132
+ return TableInfo (exists, String[])
133
+ end
134
+ end
135
+
122
136
"""
123
137
source |> SQLite.load!(db::SQLite.DB, tablename::String; temp::Bool=false, ifnotexists::Bool=false, analyze::Bool=false)
124
138
SQLite.load!(source, db, tablename; temp=false, ifnotexists=false, analyze::Bool=false)
@@ -136,22 +150,36 @@ load!(db::DB, table::AbstractString="sqlitejl_"*Random.randstring(5); kwargs...)
136
150
function load! (itr, db:: DB , name:: AbstractString = " sqlitejl_" * Random. randstring (5 ); kwargs... )
137
151
# check if table exists
138
152
nm = esc_id (name)
139
- status = execute (db, " pragma table_info( $nm ) " )
153
+ db_tableinfo = tableinfo (db, nm )
140
154
rows = Tables. rows (itr)
141
155
sch = Tables. schema (rows)
142
- return load! (sch, rows, db, nm, name, status == SQLITE_DONE ; kwargs... )
156
+ return load! (sch, rows, db, nm, name, db_tableinfo ; kwargs... )
143
157
end
144
158
145
159
checkdupnames (names) = length (unique (map (x-> lowercase (String (x)), names))) == length (names) || error (" duplicate case-insensitive column names detected; sqlite doesn't allow duplicate column names and treats them case insensitive" )
146
160
147
- function load! (sch:: Tables.Schema , rows, db:: DB , nm:: AbstractString , name, shouldcreate; temp:: Bool = false , ifnotexists:: Bool = false , analyze:: Bool = false )
161
+ function checknames (:: Tables.Schema{names} , db_names:: Vector{String} ) where {names}
162
+ table_names = Set (string .(names))
163
+ db_names = Set (db_names)
164
+
165
+ if table_names != db_names
166
+ error (" Error loading, column names from table $(collect (table_names)) do not match database names $(collect (db_names)) " )
167
+ end
168
+ end
169
+
170
+ function load! (sch:: Tables.Schema , rows, db:: DB , nm:: AbstractString , name, db_tableinfo:: TableInfo ; temp:: Bool = false , ifnotexists:: Bool = false , analyze:: Bool = false )
148
171
# check for case-insensitive duplicate column names (sqlite doesn't allow)
149
172
checkdupnames (sch. names)
150
173
# create table if needed
151
- shouldcreate && createtable! (db, nm, sch; temp= temp, ifnotexists= ifnotexists)
174
+ if db_tableinfo. exists
175
+ checknames (sch, db_tableinfo. names)
176
+ else
177
+ createtable! (db, nm, sch; temp= temp, ifnotexists= ifnotexists)
178
+ end
152
179
# build insert statement
180
+ columns = join (sch. names, " ," )
153
181
params = chop (repeat (" ?," , length (sch. names)))
154
- stmt = Stmt (db, " INSERT INTO $nm VALUES ($params )" )
182
+ stmt = Stmt (db, " INSERT INTO $nm ( $columns ) VALUES ($params )" )
155
183
# start a transaction for inserting rows
156
184
transaction (db) do
157
185
for row in rows
@@ -167,18 +195,23 @@ function load!(sch::Tables.Schema, rows, db::DB, nm::AbstractString, name, shoul
167
195
end
168
196
169
197
# unknown schema case
170
- function load! (:: Nothing , rows, db:: DB , nm:: AbstractString , name, shouldcreate ; temp:: Bool = false , ifnotexists:: Bool = false , analyze:: Bool = false )
198
+ function load! (:: Nothing , rows, db:: DB , nm:: AbstractString , name, db_tableinfo :: TableInfo ; temp:: Bool = false , ifnotexists:: Bool = false , analyze:: Bool = false )
171
199
state = iterate (rows)
172
200
state === nothing && return nm
173
201
row, st = state
174
202
names = propertynames (row)
175
203
sch = Tables. Schema (names, nothing )
176
204
checkdupnames (sch. names)
177
205
# create table if needed
178
- shouldcreate && createtable! (db, nm, sch; temp= temp, ifnotexists= ifnotexists)
206
+ if db_tableinfo. exists
207
+ checknames (sch, db_tableinfo. names)
208
+ else
209
+ createtable! (db, nm, sch; temp= temp, ifnotexists= ifnotexists)
210
+ end
179
211
# build insert statement
180
212
params = chop (repeat (" ?," , length (names)))
181
- stmt = Stmt (db, " INSERT INTO $nm VALUES ($params )" )
213
+ columns = join (sch. names, " ," )
214
+ stmt = Stmt (db, " INSERT INTO $nm ($columns ) VALUES ($params )" )
182
215
# start a transaction for inserting rows
183
216
transaction (db) do
184
217
while true
0 commit comments