diff --git a/src/tables.jl b/src/tables.jl index 206f9b7..fab99c2 100644 --- a/src/tables.jl +++ b/src/tables.jl @@ -179,7 +179,7 @@ function DBInterface.execute( end """ - SQLite.createtable!(db::SQLite.DB, table_name, schema::Tables.Schema; temp=false, ifnotexists=true) + SQLite.createtable!(db::SQLite.DB, table_name, schema::Tables.Schema; temp=false, ifnotexists=true, strict=false) 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)` 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`). @@ -193,6 +193,7 @@ function createtable!( ::Tables.Schema{names,types}; temp::Bool = false, ifnotexists::Bool = true, + strict::Bool = false ) where {names,types} temp = temp ? "TEMP" : "" ifnotexists = ifnotexists ? "IF NOT EXISTS" : "" @@ -203,7 +204,7 @@ function createtable!( sqlitetype(types !== nothing ? fieldtype(types, i) : Any), ) for i in eachindex(names) ] - sql = "CREATE $temp TABLE $ifnotexists $(esc_id(string(name))) ($(join(columns, ',')))" + sql = "CREATE $temp TABLE $ifnotexists $(esc_id(string(name))) ($(join(columns, ','))) $(strict ? "STRICT" : "")" return execute(db, sql) end @@ -303,6 +304,7 @@ function load!( st = nothing; temp::Bool = false, ifnotexists::Bool = false, + strict::Bool = false, on_conflict::Union{String,Nothing} = nothing, replace::Bool = false, analyze::Bool = false, @@ -313,7 +315,7 @@ function load!( if db_tableinfo !== nothing checknames(sch, db_tableinfo.name) else - createtable!(db, name, sch; temp = temp, ifnotexists = ifnotexists) + createtable!(db, name, sch; temp = temp, ifnotexists = ifnotexists, strict = strict) end # build insert statement columns = join(esc_id.(string.(sch.names)), ",") diff --git a/test/runtests.jl b/test/runtests.jl index b2a8927..b57c2fa 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -799,6 +799,18 @@ end @test_throws SQLiteException SQLite.load!(tbl3, db, "data") end + @testset "PR #343: strict (and only strict) tables should error if types don't match" begin + db = SQLite.DB() + + tbl1 = (a = [1, 2, 3], b = [4, 5, 6]) + SQLite.load!(tbl1, db, "data_default") + SQLite.load!(tbl1, db, "data_strict", strict=true) + + tbl2 = (a = ["a", "b", "c"], b=[7, 8, 9]) + SQLite.load!(tbl2, db, "data_default") + @test_throws SQLiteException SQLite.load!(tbl2, db, "data_strict") + end + @testset "Test busy_timeout" begin db = SQLite.DB() @test SQLite.busy_timeout(db, 300) == 0