WIP Refactor DB module to separate out common from PM_API=specific code. Continued work on parsing.

This commit is contained in:
2019-02-18 10:14:42 -06:00
parent 77084565a1
commit 7bba4a0ad7
4 changed files with 229 additions and 85 deletions

View File

@ -2,53 +2,7 @@ import db_postgres, macros, options, postgres, sequtils, strutils, times,
timeutils, unicode, uuids
import ./models
import ./db_util
proc newMutateClauses(): MutateClauses =
return MutateClauses(
columns: @[],
placeholders: @[],
values: @[])
proc createRecord*[T](db: DbConn, rec: T): T =
var mc = newMutateClauses()
populateMutateClauses(rec, true, mc)
# Confusingly, getRow allows inserts and updates. We use it to get back the ID
# we want from the row.
let newIdStr = db.getValue(sql(
"INSERT INTO " & tableName(rec) &
" (" & mc.columns.join(",") & ") " &
" VALUES (" & mc.placeholders.join(",") & ") " &
" RETURNING id"), mc.values)
result = rec
result.id = parseUUID(newIdStr)
proc updateRecord*[T](db: DbConn, rec: T): bool =
var mc = newMutateClauses()
populateMutateClauses(rec, false, mc)
let setClause = zip(mc.columns, mc.placeholders).mapIt(it.a & " = " it.b).join(',')
let numRowsUpdated = db.execAffectedRows(sql(
"UPDATE " & tableName(rec) &
" SET " & setClause &
" WHERE id = ? "), mc.values.concat(@[rec.id]))
return numRowsUpdated > 0;
template getRecord*(db: DbConn, modelType: type, id: UUID): untyped =
let row = db.getRow(sql(
"SELECT " & columnNamesForModel(modelType).join(",") &
" FROM " & tableName(modelType) &
" WHERE id = ?"), @[$id])
rowToModel(modelType, row)
template getAllRecords*(db: DbConn, modelType: type): untyped =
db.getAllRows(sql(
"SELECT " & columnNamesForModel(modelType).join(",") &
" FROM " & tableName(modelType)))
.mapIt(rowToModel(modelType, it))
import ./db_common
# proc create: Typed create methods for specific records
proc createUser*(db: DbConn, user: User): User = return db.createRecord(user)
@ -57,35 +11,7 @@ proc createMeasure*(db: DbConn, measure: Measure): Measure = return db.createRec
proc createValue*(db: DbConn, value: Value): Value = return db.createRecord(value)
proc getUser*(db: DbConn, id: UUID): User = return db.getRecord(User, id)
proc getUser*(db: DbConn, id: string): User = return db.getRecord(User, parseUUID(id))
proc getApiToken*(db: DbConn, id: UUID): ApiToken = return db.getRecord(ApiToken, id)
proc getMeasure*(db: DbConn, id: UUID): Measure = return db.getRecord(Measure, id)
#proc getValue*(db: DbConn, id: UUID): Value = return db.getRecord(Value, id)
when isMainModule:
let db = open("", "", "", "host=localhost port=5500 dbname=personal_measure user=postgres password=password")
echo "Users:"
echo $db.getAllRecords(User)
echo "\nApiTokens:"
echo $db.getAllRecords(ApiToken)
echo "\nMeasures:"
let measures = db.getAllRecords(Measure)
echo $measures
echo "\tanalysis: ", measures[0].analysis[0]
#[
#echo tableName(ApiToken)
#echo $rowToModel(ApiToken, @["47400441-5c3a-4119-8acf-f616ae25c16c", "9e5460dd-b580-4071-af97-c1cbdedaae12", "Test Token", "5678", ""])
for row in db.fastRows(sql"SELECT * FROM api_tokens"):
echo $rowToModel(ApiToken, row);
let u = User(
displayName: "Bob",
email: "bob@bobsco.com",
hashedPwd: "test")
]#
proc getValue*(db: DbConn, id: UUID): Value = return db.getRecord(Value, id)

View File

@ -0,0 +1,50 @@
import db_postgres, macros, options, sequtils, uuids
import ./db_util
proc newMutateClauses(): MutateClauses =
return MutateClauses(
columns: @[],
placeholders: @[],
values: @[])
proc createRecord*[T](db: DbConn, rec: T): T =
var mc = newMutateClauses()
populateMutateClauses(rec, true, mc)
# Confusingly, getRow allows inserts and updates. We use it to get back the ID
# we want from the row.
let newIdStr = db.getValue(sql(
"INSERT INTO " & tableName(rec) &
" (" & mc.columns.join(",") & ") " &
" VALUES (" & mc.placeholders.join(",") & ") " &
" RETURNING id"), mc.values)
result = rec
result.id = parseUUID(newIdStr)
proc updateRecord*[T](db: DbConn, rec: T): bool =
var mc = newMutateClauses()
populateMutateClauses(rec, false, mc)
let setClause = zip(mc.columns, mc.placeholders).mapIt(it.a & " = " it.b).join(',')
let numRowsUpdated = db.execAffectedRows(sql(
"UPDATE " & tableName(rec) &
" SET " & setClause &
" WHERE id = ? "), mc.values.concat(@[rec.id]))
return numRowsUpdated > 0;
template getRecord*(db: DbConn, modelType: type, id: UUID): untyped =
let row = db.getRow(sql(
"SELECT " & columnNamesForModel(modelType).join(",") &
" FROM " & tableName(modelType) &
" WHERE id = ?"), @[$id])
rowToModel(modelType, row)
template getAllRecords*(db: DbConn, modelType: type): untyped =
db.getAllRows(sql(
"SELECT " & columnNamesForModel(modelType).join(",") &
" FROM " & tableName(modelType)))
.mapIt(rowToModel(modelType, it))

View File

@ -140,10 +140,11 @@ proc createParseStmt*(t, value: NimNode): NimNode =
elif t.typeKind == ntySequence:
let innerType = t[1]
let parseStmts = createParseStmt(innerType, ident("it"))
echo parseStmts.treeRepr
result.add quote do:
# TODO: for each value call the type-specific parsing logic.
#parseDbArray(`value`).mapIt(createParseStmt(it))
parseDbArray(`value`)
parseDbArray(`value`).mapIt(`parseStmts`)
elif t.typeKind == ntyString:
result.add quote do: