update
This commit is contained in:
275
src/dbUtil.jl
275
src/dbUtil.jl
@@ -9,6 +9,38 @@ using ..util
|
||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
||||
|
||||
|
||||
"""
|
||||
dictToPostgresKeyValueString - Convert dictionary to PostgreSQL key-value string format
|
||||
|
||||
This function takes a dictionary and converts it into a PostgreSQL-compatible key-value string
|
||||
format suitable for storage in a TEXT field. The output format uses curly braces with comma-separated
|
||||
key-value pairs, where string values are quoted.
|
||||
|
||||
# Function Workflow:
|
||||
1. Iterates through dictionary key-value pairs
|
||||
2. Handles nested dictionaries by recursively converting them
|
||||
3. Wraps string values in double quotes
|
||||
4. Formats numeric and other values without quotes
|
||||
5. Returns a PostgreSQL-compatible key-value string enclosed in curly braces
|
||||
|
||||
# Arguments:
|
||||
- `dict::Dict` - Dictionary containing key-value pairs to convert
|
||||
|
||||
# Return:
|
||||
- A String in PostgreSQL key-value format: "{key1: value1, key2: \"value2\", ...}"
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia> data = Dict{String, Any}(
|
||||
"name" => "John",
|
||||
"age" => 30,
|
||||
"city" => "New York"
|
||||
);
|
||||
|
||||
julia> dictToPostgresKeyValueString(data)
|
||||
"{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}"
|
||||
```
|
||||
"""
|
||||
function dictToPostgresKeyValueString(dict)
|
||||
parts = []
|
||||
for (k, v) in dict
|
||||
@@ -26,58 +58,67 @@ end
|
||||
|
||||
|
||||
|
||||
""" Get characters between specified characters.
|
||||
""" generateInsertSQL - Generate SQL INSERT statement from dictionary data
|
||||
|
||||
# Arguments
|
||||
- `text::T`
|
||||
a text being searched
|
||||
- `startChar::Char`
|
||||
start character
|
||||
- `endChar::Char`
|
||||
end character
|
||||
# Keyword Arguments
|
||||
- `endCharLocation::String`
|
||||
end character position after startChar. Can be "next" or "end". "next" means the closed
|
||||
endChar just after startChar. "end" means the furthest endChar.
|
||||
- `includeChar::Bool`
|
||||
whether to include the startChar and endChar. Default is true
|
||||
# Return
|
||||
the characters between specified characters.
|
||||
This function constructs a SQL INSERT statement by extracting values for specified columns
|
||||
from a dictionary and formatting them into a valid PostgreSQL INSERT query.
|
||||
|
||||
# Function Workflow:
|
||||
1. Iterates through the dictionary key-value pairs
|
||||
2. Filters keys to only include those present in `columnToInsert`
|
||||
3. Collects column names and their corresponding values
|
||||
4. Constructs the final SQL INSERT statement
|
||||
|
||||
# Arguments:
|
||||
- `table_name::String` - Name of the database table to insert into
|
||||
- `columnToInsert::Vector{Symbol}` - List of column names to include in the INSERT statement
|
||||
- `data::Dict{Symbol, Any}` - Dictionary containing column-value pairs for the insert
|
||||
|
||||
# Return:
|
||||
- A String containing the SQL INSERT statement
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia> using Revise
|
||||
julia> using GeneralUtils
|
||||
julia> insert_data = Dict(
|
||||
:grape => "NA",
|
||||
:acidity => "0",
|
||||
:tannin => "0",
|
||||
:country => "NA",
|
||||
:description => "NA",
|
||||
:region => "NA",
|
||||
:winery => "ccc",
|
||||
:intensity => "0",
|
||||
:sweetness => "0",
|
||||
:tasting_notes => "NA",
|
||||
:wine_name => "new_wine",
|
||||
:wine_id => "9e1deb6a-d57f-4d2c-abbe-da813f4e91ad",
|
||||
:wine_type => "NA",
|
||||
:other_attributes => "{\"attribute3\":{\"attribute5\":666,\"attribute4\":\"text\"},\"attribute1\":\"hello world\",\"attribute2\":555}",
|
||||
:fizziness => "0",
|
||||
:serving_temperature => "0",
|
||||
:additional_search_term => "{NA1,NA2}")
|
||||
```
|
||||
# TODO
|
||||
- [] update docs
|
||||
julia> using UUIDs
|
||||
|
||||
# Signature
|
||||
# Insert a single record with specific columns
|
||||
table_name = "wine"
|
||||
columnToInsert = [:acidity, :tannin, :country, :region, :winery]
|
||||
data = Dict{Symbol, Any}(
|
||||
:grape => "Cabernet Sauvignon",
|
||||
:acidity => "medium", # using descriptive scale (low/medium/full)
|
||||
:tannin => "medium-plus", # common wine descriptor
|
||||
:country => "France",
|
||||
:description => "A rich and structured red wine with notes of blackcurrant, cedar, and subtle oak.",
|
||||
:region => "Bordeaux",
|
||||
:winery => "Château Margaux",
|
||||
:intensity => "medium", # intensity is usually low/medium/full
|
||||
:sweetness => "dry", # dry/medium-dry/medium/medium-sweet/sweet
|
||||
:tasting_notes => "Blackberry, graphite, tobacco, vanilla, and subtle earth.",
|
||||
:wine_name => "Château Margaux Grand Cru",
|
||||
:wine_id => "8f3c7a2e-1b4d-4a9f-9c2e-4a8b3d6e5f7a", # UUID-like (valid hex)
|
||||
:wine_type => "Red",
|
||||
:other_attributes => Dict{String, Any}(
|
||||
"vintage" => 2018,
|
||||
"alcohol_percent" => 13.5,
|
||||
"ph" => 3.6,
|
||||
" aging_years" => 24, # years in barrel
|
||||
" producer_code" => "CM-GRAND"
|
||||
),
|
||||
:fizziness => "still",
|
||||
:serving_temperature => "16–18°C",
|
||||
:additional_search_term => ["Cabernet", "Bordeaux red", "premium wine", "CabSav"]
|
||||
)
|
||||
|
||||
julia> generateInsertSQL(table_name, columnToInsert, data)
|
||||
"INSERT INTO wine (acidity, tannin, country, region, winery) VALUES ('medium', 'medium-plus', 'France', 'Bordeaux', 'Château Margaux');"
|
||||
```
|
||||
"""
|
||||
function generateInsertSQL(table_name::String, columnToInsert::Vector{Symbol},
|
||||
insert_data::Dict{Symbol, Any})
|
||||
function generateInsertSQL(table_name::String, columnToInsert::Vector{Symbol}, data::Dict{Symbol, Any})
|
||||
columns = String[]
|
||||
values = String[]
|
||||
|
||||
for (key, value) in insert_data
|
||||
for (key, value) in data
|
||||
if key ∈ columnToInsert
|
||||
push!(columns, string(key))
|
||||
push!(values, "'$value'") #[] number should not wrapped in ''
|
||||
@@ -89,113 +130,57 @@ function generateInsertSQL(table_name::String, columnToInsert::Vector{Symbol},
|
||||
|
||||
return "INSERT INTO $table_name ($columns_str) VALUES ($values_str);"
|
||||
end
|
||||
# function generateInsertSQL(table_name::String, insert_data::Dict{Symbol, Any})
|
||||
# columns = String[]
|
||||
# values = String[]
|
||||
|
||||
# for (key, value) in insert_data
|
||||
# push!(columns, string(key))
|
||||
# if key == :other_attributes
|
||||
# push!(values, "'$value'")
|
||||
# else
|
||||
# push!(values, "'$value'")
|
||||
# end
|
||||
# end
|
||||
|
||||
# columns_str = join(columns, ", ")
|
||||
# values_str = join(values, ", ")
|
||||
|
||||
# return "INSERT INTO $table_name ($columns_str) VALUES ($values_str);"
|
||||
# end
|
||||
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------- 100 --------------------------------------------- #
|
||||
|
||||
""" generateUpdateSQL - Generate SQL UPDATE statement from dictionary data
|
||||
|
||||
This function constructs a SQL UPDATE statement by updating multiple columns
|
||||
based on a primary key condition.
|
||||
|
||||
# Arguments:
|
||||
- `table_name::String` - Name of the database table to update
|
||||
- `pk_column::Symbol` - The primary key column name
|
||||
- `pk_value` - The primary key value (used in WHERE clause)
|
||||
- `data::Dict{Symbol, Any}` - Dictionary containing column-value pairs to update
|
||||
|
||||
# Return:
|
||||
- A String containing the SQL UPDATE statement
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia> using UUIDs
|
||||
|
||||
# Update multiple columns using a dictionary
|
||||
table_name = "wine"
|
||||
pk_column = :wine_id
|
||||
pk_value = "8f3c7a2e-1b4d-4a9f-9c2e-4a8b3d6e5f7a"
|
||||
data = Dict{Symbol, Any}(
|
||||
:acidity => "full",
|
||||
:tannin => "medium",
|
||||
:country => "Italy"
|
||||
)
|
||||
|
||||
julia> generateUpdateSQL(table_name, pk_column, pk_value, data)
|
||||
"UPDATE wine SET acidity = 'full', tannin = 'medium', country = 'Italy' WHERE wine_id = '8f3c7a2e-1b4d-4a9f-9c2e-4a8b3d6e5f7a';"
|
||||
```
|
||||
"""
|
||||
example:
|
||||
|
||||
insert_data = Dict(
|
||||
:grape => "NA",
|
||||
:acidity => "0",
|
||||
:tannin => "0",
|
||||
:country => "NA",
|
||||
:description => "NA",
|
||||
:region => "NA",
|
||||
:winery => "ccc",
|
||||
:intensity => "0",
|
||||
:sweetness => "0",
|
||||
:tasting_notes => "NA",
|
||||
:wine_name => "new_wine",
|
||||
:wine_id => "9e1deb6a-d57f-4d2c-abbe-da813f4e91ad",
|
||||
:wine_type => "NA",
|
||||
:other_attributes => "{\"attribute3\":{\"attribute5\":666,\"attribute4\":\"text\"},\"attribute1\":\"hello world\",\"attribute2\":555}",
|
||||
:fizziness => "0",
|
||||
:serving_temperature => "0",
|
||||
:additional_search_term => "{NA1,NA2}")
|
||||
|
||||
id_keys is the primary key columns
|
||||
"""
|
||||
# function generateUpdateSQL(table_name::String, update_data::Dict{Symbol, Any}, id_keys::Vector{Symbol})
|
||||
# set_clauses = String[]
|
||||
# where_clauses = String[]
|
||||
|
||||
# for (key, value) in update_data
|
||||
# if key in id_keys
|
||||
# push!(where_clauses, "$key = '$value'")
|
||||
# else
|
||||
# if key == :other_attributes
|
||||
# push!(set_clauses, "$key = '$value'")
|
||||
# else
|
||||
# push!(set_clauses, "$key = '$value'")
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
||||
# set_clause = join(set_clauses, ", ")
|
||||
# where_clause = join(where_clauses, " AND ")
|
||||
|
||||
# return "UPDATE $table_name SET $set_clause WHERE $where_clause;"
|
||||
# end
|
||||
|
||||
function generateUpdateSQL(table_name::String, columnToUpdate::Vector{Symbol},
|
||||
updatedata::Dict{Symbol, Any}, id_keys::Vector{Symbol})
|
||||
|
||||
set_clauses = String[]
|
||||
where_clauses = String[]
|
||||
|
||||
for (key, value) in updatedata
|
||||
if key in id_keys
|
||||
push!(where_clauses, "$key = '$value'")
|
||||
else
|
||||
if key ∈ columnToUpdate # update only specified columns
|
||||
push!(set_clauses, "$key = '$value'")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
set_clause = join(set_clauses, ", ")
|
||||
where_clause = join(where_clauses, " AND ")
|
||||
|
||||
return "UPDATE $table_name SET $set_clause WHERE $where_clause;"
|
||||
function generateUpdateSQL(table_name::String, pk_column::Symbol, pk_value, data::Dict{Symbol, Any})
|
||||
# Build SET clause
|
||||
set_parts = String[]
|
||||
for (key, value) in data
|
||||
value_str = isa(value, AbstractString) ? "'$value'" : "$value"
|
||||
push!(set_parts, "$(string(key)) = $value_str")
|
||||
end
|
||||
|
||||
set_clause = join(set_parts, ", ")
|
||||
|
||||
# Handle primary key value
|
||||
pk_val_str = isa(pk_value, AbstractString) ? "'$pk_value'" : "$pk_value"
|
||||
|
||||
return "UPDATE $table_name SET $set_clause WHERE $pk_column = $pk_val_str;"
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end # module
|
||||
Reference in New Issue
Block a user