Current section
Files
Jump to
Current section
Files
src/db/decoder.gleam
import db/schema
import gleam/dynamic
import gleam/int
import gleam/io
import gleam/list
import gleam/pgo
import gleam/string
import simplifile.{append, read, write}
// Function to append type definitions to an existing file
pub fn generate_row_type(table: schema.Table) {
let columns = table.columns
let fields =
columns
|> list.map(fn(column) {
case column {
schema.StringColumn(name, _) -> name <> ": String"
schema.IntColumn(name) -> name <> ": Int"
schema.BoolColumn(name) -> name <> ": Bool"
schema.SerialColumn(name) -> name <> ": Int"
schema.ForeignKeyColumn(name, _, _, ref_type) ->
name <> ": " <> ref_type
_ -> ""
}
})
|> string.join(", ")
let capitalized_name = string.capitalise(table.name)
let unique_id = simple_hash(columns)
let path = "./src/funs/" <> table.name <> ".gleam"
let type_name = capitalized_name <> "Row" <> unique_id
let type_definition =
"pub type " <> type_name <> " { " <> type_name <> "(" <> fields <> ") }\n"
simplifile.create_directory("./src/funs/")
// Read the existing file content
let existing_content = case read(path) {
Ok(content) -> content
Error(_) -> ""
}
// Check if the type name already exists
case string.contains(existing_content, type_name) {
True -> io.debug("Type definition already exists, skipping generation.")
False -> {
append(to: path, contents: type_definition)
io.debug("Generating...")
}
}
}
// Function to append decoder functions to an existing file
pub fn generate_decoder_code(table: schema.Table) {
let columns = table.columns
let capitalized_name = string.capitalise(table.name)
let unique_id = simple_hash(columns)
let decoder_name = table.name <> "_decoder_" <> string.lowercase(unique_id)
let path = "./src/funs/" <> table.name <> "_decoder.gleam"
// Read the existing file content
let existing_content = case read(path) {
Ok(content) -> content
Error(_) -> ""
}
// Check if the necessary imports are already present
let import_schema = "import funs/" <> table.name
let import_decode = "import decode"
let imports =
case string.contains(existing_content, import_schema) {
True -> ""
False -> import_schema <> "\n"
}
<> case string.contains(existing_content, import_decode) {
True -> ""
False -> import_decode <> "\n"
}
let parameters =
columns
|> list.map(fn(column) { "use " <> column.name <> " <- decode.parameter" })
|> string.join("\n")
let fields =
columns
|> list.index_map(fn(column, index) {
case column {
schema.StringColumn(name, _) ->
" |> decode.field(" <> int.to_string(index) <> ", decode.string)"
schema.IntColumn(name) ->
" |> decode.field(" <> int.to_string(index) <> ", decode.int)"
schema.BoolColumn(name) ->
" |> decode.field(" <> int.to_string(index) <> ", decode.bool)"
schema.SerialColumn(name) ->
" |> decode.field(" <> int.to_string(index) <> ", decode.int)"
schema.ForeignKeyColumn(name, _, _, ref_type) ->
" |> decode.field("
<> int.to_string(index)
<> ", decode."
<> string.lowercase(ref_type)
<> ")"
_ -> " |> decode.field(" <> int.to_string(index) <> ", decode.string)"
}
})
|> string.join("\n")
let decoder_code =
imports
<> "pub fn "
<> decoder_name
<> "() {\n"
<> " decode.into({\n"
<> parameters
<> "\n "
<> table.name
<> "."
<> capitalized_name
<> "Row"
<> unique_id
<> "("
<> columns
|> list.map(fn(column) { column.name <> ": " <> column.name })
|> string.join(", ")
<> ")\n })\n"
<> fields
<> "\n}\n"
// Check if the decoder function name already exists
case string.contains(existing_content, decoder_name) {
True -> io.debug("Decoder function already exists, skipping generation.")
False -> {
simplifile.create_directory("./src/funs/")
append(to: path, contents: decoder_code)
io.debug("Generating...")
}
}
}
fn simple_hash(columns: List(schema.Column)) -> String {
""
}