module DatabaseSupport using SearchLight, SearchLightPostgreSQL, LibPQ using DataFrames export exist_in_table, insert_into_table, update_table, select_from_table, delete_from_table, add_foreign_key, set_default options = SearchLight.Configuration.read_db_connection_data("db/connection.yml") conn = SearchLight.connect(options) function format(x) if (x isa String) || (x isa Symbol) return string("'",x,"'") elseif (isnothing(x) || ismissing(x)) return "NULL" else return x end end function insert_into_table(table_name,dict_values,other="") names_string = join(keys(dict_values),", ") vals_raw = values(dict_values) vals = map(x -> format(x),vals_raw) vals_string = join(values(vals),", ") query = "INSERT INTO $table_name ($names_string) VALUES ($vals_string) " * other return SearchLight.query(query) end function delete_from_table(table_name,where_data) query = "DELETE FROM $table_name" if !isnothing(where_data) query *= where_query(where_data) end SearchLight.query(query) end function update_table(table_name,dict_values; where_data=nothing) ns = collect(keys(dict_values)) vals_raw = values(dict_values) vals = map(x -> format(x),vals_raw) ns_vals = join(map((x,y) -> string(x, " = ",y),ns,vals),", ") query = "UPDATE $table_name SET $ns_vals" if !isnothing(where_data) query *= where_query(where_data) end cur = SearchLight.query(query) return DataFrame(cur) end function where_query(pair::Pair) if isnothing(pair[2]) return " WHERE $(pair[1]) is null" else return " WHERE $(pair[1]) = $(pair[2])" end end function where_query(data::Vector{<:Pair}) conds = String[] for pair in data if isnothing(pair[2]) push!(conds, "$(pair[1]) is null") else push!(conds,"$(pair[1]) = $(pair[2])") end end query = " WHERE "*join(conds," AND ") return query end function join_query(data::Vector{<:Vector},table_name) query = "" for v in data table_join = v[1] column_join = v[2] column2_join = v[3] query *= " JOIN $table_join ON $(table_name).$(column_join) = $(table_join).$(column2_join)" end return query end function join_query(data::Vector{<:Union{String,Symbol}},table_name) table_join = data[1] column_join = data[2] column2_join = data[3] query = " JOIN $table_join ON $(table_name).$(column_join) = $(table_join).$(column2_join)" return query end function select_query(table::Pair) table_name = table[1] cols = table[2] if isnothing(cols) cols_query = "*" else cols_query = join(cols,", ") end query = "SELECT $cols_query FROM $table_name" return query end function as_query(table_name,col_name::Symbol) return table_name*"."*String(col_name) end function as_query(table_name,col_name::String) return table_name*"."*col_name end function as_query(table_name,col_name::Pair) return table_name*"."*col_name[1]*" AS "*col_name[2] end function select_query(tables::Vector{<:Pair}) tables_query_ar = String[] cols_query_ar = String[] for table in tables table_name = table[1] cols = table[2] push!(tables_query_ar,table_name) if isnothing(cols) push!(cols_query_ar, table_name*".*") else push!(cols_query_ar, join(map(col_name -> as_query(table_name,col_name),cols),", ")) end end tables_query = join(tables_query_ar,", ") cols_query = join(cols_query_ar,", ") query = "SELECT $cols_query FROM $(tables_query)" return query end function select_from_table(tables; where_data = nothing) query = select_query(tables) if !isnothing(where_data) query *= where_query(where_data) end cur = SearchLight.query(query) return DataFrame(cur) end function exist_in_table(table_name,where_data) cur = SearchLight.query("SELECT * FROM $table_name "*where_query(where_data)*" LIMIT 1") t = DataFrame(cur) return size(t,1)>0 end function add_foreign_key(table,name,table2,name2) query = """ ALTER TABLE $table ADD CONSTRAINT fk_$(table)_$(table2)_$(name) FOREIGN KEY ($name) REFERENCES $table2 ($name2);""" SearchLight.query(query) end function set_default(table,column,value) query = """ ALTER TABLE $table ALTER COLUMN $column SET DEFAULT $value ;""" SearchLight.query(query) end end