Skip to content

Commit 079f6c2

Browse files
authored
add strict option to create_table! and load! (#343)
Adds strict=false keyword to createtable! and load! to support SQLite STRICT tables. Fixes #327. Thanks @aplavin!
1 parent 2716ac0 commit 079f6c2

2 files changed

Lines changed: 17 additions & 3 deletions

File tree

src/tables.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ function DBInterface.execute(
187187
end
188188

189189
"""
190-
SQLite.createtable!(db::SQLite.DB, table_name, schema::Tables.Schema; temp=false, ifnotexists=true)
190+
SQLite.createtable!(db::SQLite.DB, table_name, schema::Tables.Schema; temp=false, ifnotexists=true, strict=false)
191191
192192
Create a table in `db` with name `table_name`, according to `schema`, which is a set of column names and types, constructed like `Tables.Schema(names, types)`
193193
where `names` can be a vector or tuple of String/Symbol column names, and `types` is a vector or tuple of sqlite-compatible types (`Int`, `Float64`, `String`, or unions of `Missing`).
@@ -201,6 +201,7 @@ function createtable!(
201201
::Tables.Schema{names,types};
202202
temp::Bool = false,
203203
ifnotexists::Bool = true,
204+
strict::Bool = false
204205
) where {names,types}
205206
temp = temp ? "TEMP" : ""
206207
ifnotexists = ifnotexists ? "IF NOT EXISTS" : ""
@@ -211,7 +212,7 @@ function createtable!(
211212
sqlitetype(types !== nothing ? fieldtype(types, i) : Any),
212213
) for i in eachindex(names)
213214
]
214-
sql = "CREATE $temp TABLE $ifnotexists $(esc_id(string(name))) ($(join(columns, ',')))"
215+
sql = "CREATE $temp TABLE $ifnotexists $(esc_id(string(name))) ($(join(columns, ','))) $(strict ? "STRICT" : "")"
215216
return execute(db, sql)
216217
end
217218

@@ -311,6 +312,7 @@ function load!(
311312
st = nothing;
312313
temp::Bool = false,
313314
ifnotexists::Bool = false,
315+
strict::Bool = false,
314316
on_conflict::Union{String,Nothing} = nothing,
315317
replace::Bool = false,
316318
analyze::Bool = false,
@@ -321,7 +323,7 @@ function load!(
321323
if db_tableinfo !== nothing
322324
checknames(sch, db_tableinfo.name)
323325
else
324-
createtable!(db, name, sch; temp = temp, ifnotexists = ifnotexists)
326+
createtable!(db, name, sch; temp = temp, ifnotexists = ifnotexists, strict = strict)
325327
end
326328
# build insert statement
327329
columns = join(esc_id.(string.(sch.names)), ",")

test/runtests.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,18 @@ end
799799
@test_throws SQLiteException SQLite.load!(tbl3, db, "data")
800800
end
801801

802+
@testset "PR #343: strict (and only strict) tables should error if types don't match" begin
803+
db = SQLite.DB()
804+
805+
tbl1 = (a = [1, 2, 3], b = [4, 5, 6])
806+
SQLite.load!(tbl1, db, "data_default")
807+
SQLite.load!(tbl1, db, "data_strict", strict=true)
808+
809+
tbl2 = (a = ["a", "b", "c"], b=[7, 8, 9])
810+
SQLite.load!(tbl2, db, "data_default")
811+
@test_throws SQLiteException SQLite.load!(tbl2, db, "data_strict")
812+
end
813+
802814
@testset "Test busy_timeout" begin
803815
db = SQLite.DB()
804816
@test SQLite.busy_timeout(db, 300) == 0

0 commit comments

Comments
 (0)