Skip to content

Commit

Permalink
chore: add bulk insert
Browse files Browse the repository at this point in the history
  • Loading branch information
Jcharis committed Sep 8, 2024
1 parent c0ff07d commit bf09018
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 6 deletions.
10 changes: 5 additions & 5 deletions Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

julia_version = "1.10.5"
manifest_format = "2.0"
project_hash = "77cfb56db7be07d0a299c01d2c12a5f6b81adeb1"
project_hash = "3e5dc5c69763903a4a2249152de7920becf16518"

[[deps.ANSIColoredPrinters]]
git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c"
Expand Down Expand Up @@ -103,9 +103,9 @@ version = "0.9.3"

[[deps.Documenter]]
deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"]
git-tree-sha1 = "9d29b99b6b2b6bc2382a4c8dbec6eb694f389853"
git-tree-sha1 = "5a1ee886566f2fa9318df1273d8b778b9d42712d"
uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
version = "1.6.0"
version = "1.7.0"

[[deps.DocumenterTools]]
deps = ["AbstractTrees", "Base64", "DocStringExtensions", "Documenter", "FileWatching", "Gumbo", "LibGit2", "OpenSSH_jll", "Sass"]
Expand Down Expand Up @@ -553,9 +553,9 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[deps.TimeZones]]
deps = ["Dates", "Downloads", "InlineStrings", "Mocking", "Printf", "Scratch", "TZJData", "Unicode", "p7zip_jll"]
git-tree-sha1 = "b92aebdd3555f3a7e3267cf17702033c2814ef48"
git-tree-sha1 = "8323074bc977aa85cf5ad71099a83ac75b0ac107"
uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53"
version = "1.18.0"
version = "1.18.1"
weakdeps = ["RecipesBase"]

[deps.TimeZones.extensions]
Expand Down
4 changes: 4 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ SQLite = "0aa819cd-b072-5ff4-a722-6bc24af294d9"

[compat]
julia = "1.10.5"
DataFrames = "1.6.1"
DocumenterTools = "0.1.19"
LibPQ = "1.17.1"
SQLite = "1.6.1"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
64 changes: 64 additions & 0 deletions src/Jorm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export create_table,delete_table
export read_one_sql,insert_sql,update_sql,delete_sql,filter_by_sql,groupby_sql,read_all_sql
export read_one,insert!,update!,delete!,read_all
export delete_db,drop_all_tables,backup_sqlite_db,backup_postgresql_db,serialize_to_list
export bulk_insert_sql,bulk_insert!


"""
Expand Down Expand Up @@ -375,6 +376,69 @@ function groupby_sql(table_name; group_by_columns, select_columns = "*", having_
return query, having_params
end

"""
bulk_insert_sql(db::SQLite.DB, model::Type, data::Vector{model})
Generate SQL insert query for bulk insertion
"""
# Function to perform bulk insert
function bulk_insert_sql(model::Type, data::Vector)
num_rows = length(data)
num_fields = length(fieldnames(model))
params = Any[getfield(row, field) for row in data for field in fieldnames(model)]

# Construct the SQL query
columns = join(fieldnames(model), ", ")
placeholders = join(repeat("?", length(fieldnames(model))), ", ")

# Construct rows with placeholders
rows = []
for _ in 1:num_rows
push!(rows, "($placeholders)")
end
rows_str = join(rows, ", ")

# Construct the final query
query = "INSERT INTO $(tablename(model)) ($columns) VALUES $rows_str"

return RawSQL(query), params
end


"""
bulk_insert!(db::SQLite.DB, model::Type, data::Vector{model})
Insert or Add data to the DB for a given model in bulk
"""
# Function to perform bulk insert
function bulk_insert!(db::SQLite.DB, model::Type, data::Vector)
query, params = bulk_insert_sql(model, data)

# Execute the query within a transaction for better performance
# Jorm.execute_query(db, RawSQL("BEGIN TRANSACTION;"))
Jorm.execute_query(db, query, params)
# Jorm.execute_query(db, RawSQL("COMMIT;"))
end


# function bulk_update!(db::SQLite.DB, model::Type, data::Vector{model})
# # Start a transaction for better performance
# Jorm.execute_query(db, "BEGIN TRANSACTION;")

# for item in data
# # Generate the SQL query for updating a record
# columns = join([string(field, " = ?") for field in fieldnames(model)], ", ")
# query = "UPDATE $(tablename(model)) SET $columns WHERE id = ?"

# # Prepare the parameters
# params = Any[getfield(item, field) for field in fieldnames(model)]
# push!(params, item.id) # Add the id for the WHERE clause

# # Execute the update query
# Jorm.execute_query(db, query, params)
# end

# # Commit the transaction
# Jorm.execute_query(db, "COMMIT;")
# end

include("JormUtils.jl")

Expand Down
35 changes: 34 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,37 @@ end
query, params = Jorm.groupby_sql(table_name; group_by_columns, select_columns, having_conditions, order_by_columns)
@test query == "SELECT [\"column1\", \"column2\", \"SUM(column3) AS total\"] FROM my_table GROUP BY column1, column2 HAVING SUM(column3) = ? ORDER BY column1, column2"

end
end



@testset "Bulk Insert SQL Construct" begin
# Create some sample data
data = [ BlogArticle("First Title","My Blog Post"), BlogArticle("Second Title","Second Blog Post"), BlogArticle("Third Title","My Third Post")]
@test Jorm.bulk_insert_sql(BlogArticle,data) == (RawSQL("INSERT INTO blog_article (title, content) VALUES (?, ?), (?, ?), (?, ?)"), Any["First Title", "My Blog Post", "Second Title", "Second Blog Post", "Third Title", "My Third Post"])
end


@testset "Bulk Insert" begin

connection_string = Jorm.SQLiteConnectionString(database_name="test.db")
tb = Jorm.tablename(BlogArticle)
db = Jorm.connect(connection_string)
Jorm.create_table(db,BlogArticle,tb)

data = [ BlogArticle("First Title","My Blog Post"), BlogArticle("Second Title","Second Blog Post"), BlogArticle("Third Title","My Third Post")]
Jorm.bulk_insert!(db,BlogArticle,data)

# Read all records
results = Jorm.read_all(db, BlogArticle)

@test length([i for i in results]) == 3
for (ix, row) in enumerate(results)
@test row.id == ix
end

# Close the database connection
Jorm.disconnect(db)
# Jorm.delete_db(connection_string)

end
Binary file added test/test.db
Binary file not shown.

0 comments on commit bf09018

Please sign in to comment.