DB changes, getXXXBy -> findXXXBy, add PG-specific timestamp parse function.
This commit is contained in:
parent
c98497526e
commit
33eff538f8
@ -4,6 +4,8 @@ import db_postgres, macros, options, postgres, sequtils, strutils,
|
|||||||
import ./models
|
import ./models
|
||||||
import ./db_common
|
import ./db_common
|
||||||
|
|
||||||
|
export db_common.NotFoundError
|
||||||
|
|
||||||
type
|
type
|
||||||
PMApiDb* = ref object
|
PMApiDb* = ref object
|
||||||
conn: DbConn
|
conn: DbConn
|
||||||
@ -15,7 +17,13 @@ proc connect*(connString: string): PMApiDb =
|
|||||||
generateProcsForModels([User, ApiToken, Measure, Measurement])
|
generateProcsForModels([User, ApiToken, Measure, Measurement])
|
||||||
|
|
||||||
generateLookup(User, @["email"])
|
generateLookup(User, @["email"])
|
||||||
|
|
||||||
generateLookup(ApiToken, @["userId"])
|
generateLookup(ApiToken, @["userId"])
|
||||||
generateLookup(ApiToken, @["hashedToken"])
|
generateLookup(ApiToken, @["hashedToken"])
|
||||||
|
|
||||||
generateLookup(Measure, @["userId"])
|
generateLookup(Measure, @["userId"])
|
||||||
|
generateLookup(Measure, @["userId", "id"])
|
||||||
|
generateLookup(Measure, @["userId", "slug"])
|
||||||
|
|
||||||
generateLookup(Measurement, @["measureId"])
|
generateLookup(Measurement, @["measureId"])
|
||||||
|
generateLookup(Measurement, @["measureId", "id"])
|
||||||
|
@ -4,6 +4,8 @@ from unicode import capitalize
|
|||||||
|
|
||||||
import ./db_util
|
import ./db_util
|
||||||
|
|
||||||
|
type NotFoundError* = object of CatchableError
|
||||||
|
|
||||||
proc newMutateClauses(): MutateClauses =
|
proc newMutateClauses(): MutateClauses =
|
||||||
return MutateClauses(
|
return MutateClauses(
|
||||||
columns: @[],
|
columns: @[],
|
||||||
@ -50,11 +52,11 @@ template getRecord*(db: DbConn, modelType: type, id: UUID): untyped =
|
|||||||
" WHERE id = ?"), @[$id])
|
" WHERE id = ?"), @[$id])
|
||||||
|
|
||||||
if row.allIt(it.len == 0):
|
if row.allIt(it.len == 0):
|
||||||
raise newException(KeyError, "no record for id " & $id)
|
raise newException(NotFoundError, "no record for id " & $id)
|
||||||
|
|
||||||
rowToModel(modelType, row)
|
rowToModel(modelType, row)
|
||||||
|
|
||||||
template getRecordsWhere*(db: DbConn, modelType: type, whereClause: string, values: varargs[string, dbFormat]): untyped =
|
template findRecordsWhere*(db: DbConn, modelType: type, whereClause: string, values: varargs[string, dbFormat]): untyped =
|
||||||
db.getAllRows(sql(
|
db.getAllRows(sql(
|
||||||
"SELECT " & columnNamesForModel(modelType).join(",") &
|
"SELECT " & columnNamesForModel(modelType).join(",") &
|
||||||
" FROM " & tableName(modelType) &
|
" FROM " & tableName(modelType) &
|
||||||
@ -67,7 +69,7 @@ template getAllRecords*(db: DbConn, modelType: type): untyped =
|
|||||||
" FROM " & tableName(modelType)))
|
" FROM " & tableName(modelType)))
|
||||||
.mapIt(rowToModel(modelType, it))
|
.mapIt(rowToModel(modelType, it))
|
||||||
|
|
||||||
template getRowsBy*(db: DbConn, modelType: type, lookups: seq[tuple[field: string, value: string]]): untyped =
|
template findRecordsBy*(db: DbConn, modelType: type, lookups: seq[tuple[field: string, value: string]]): untyped =
|
||||||
db.getAllRows(sql(
|
db.getAllRows(sql(
|
||||||
"SELECT " & columnNamesForModel(modelType).join(",") &
|
"SELECT " & columnNamesForModel(modelType).join(",") &
|
||||||
" FROM " & tableName(modelType) &
|
" FROM " & tableName(modelType) &
|
||||||
@ -82,15 +84,15 @@ macro generateProcsForModels*(modelTypes: openarray[type]): untyped =
|
|||||||
let modelName = $(t.getType[1])
|
let modelName = $(t.getType[1])
|
||||||
let getName = ident("get" & modelName)
|
let getName = ident("get" & modelName)
|
||||||
let getAllName = ident("getAll" & modelName)
|
let getAllName = ident("getAll" & modelName)
|
||||||
let getWhereName = ident("get" & modelName & "sWhere")
|
let findWhereName = ident("find" & modelName & "sWhere")
|
||||||
let createName = ident("create" & modelName)
|
let createName = ident("create" & modelName)
|
||||||
let updateName = ident("update" & modelName)
|
let updateName = ident("update" & modelName)
|
||||||
let deleteName = ident("delete" & modelName)
|
let deleteName = ident("delete" & modelName)
|
||||||
result.add quote do:
|
result.add quote do:
|
||||||
proc `getName`*(db: PMApiDb, id: UUID): `t` = getRecord(db.conn, `t`, id)
|
proc `getName`*(db: PMApiDb, id: UUID): `t` = getRecord(db.conn, `t`, id)
|
||||||
proc `getAllName`*(db: PMApiDb): seq[`t`] = getAllRecords(db.conn, `t`)
|
proc `getAllName`*(db: PMApiDb): seq[`t`] = getAllRecords(db.conn, `t`)
|
||||||
proc `getWhereName`*(db: PMApiDb, whereClause: string, values: varargs[string, dbFormat]): seq[`t`] =
|
proc `findWhereName`*(db: PMApiDb, whereClause: string, values: varargs[string, dbFormat]): seq[`t`] =
|
||||||
return getRecordsWhere(db.conn, `t`, whereClause, values)
|
return findRecordsWhere(db.conn, `t`, whereClause, values)
|
||||||
proc `createName`*(db: PMApiDb, rec: `t`): `t` = createRecord(db.conn, rec)
|
proc `createName`*(db: PMApiDb, rec: `t`): `t` = createRecord(db.conn, rec)
|
||||||
proc `updateName`*(db: PMApiDb, rec: `t`): bool = updateRecord(db.conn, rec)
|
proc `updateName`*(db: PMApiDb, rec: `t`): bool = updateRecord(db.conn, rec)
|
||||||
proc `deleteName`*(db: PMApiDb, rec: `t`): bool = deleteRecord(db.conn, rec)
|
proc `deleteName`*(db: PMApiDb, rec: `t`): bool = deleteRecord(db.conn, rec)
|
||||||
@ -98,12 +100,12 @@ macro generateProcsForModels*(modelTypes: openarray[type]): untyped =
|
|||||||
|
|
||||||
macro generateLookup*(modelType: type, fields: seq[string]): untyped =
|
macro generateLookup*(modelType: type, fields: seq[string]): untyped =
|
||||||
let fieldNames = fields[1].mapIt($it)
|
let fieldNames = fields[1].mapIt($it)
|
||||||
let procName = ident("get" & $modelType.getType[1] & "sBy" & fieldNames.mapIt(it.capitalize).join("And"))
|
let procName = ident("find" & $modelType.getType[1] & "sBy" & fieldNames.mapIt(it.capitalize).join("And"))
|
||||||
|
|
||||||
# Create proc skeleton
|
# Create proc skeleton
|
||||||
result = quote do:
|
result = quote do:
|
||||||
proc `procName`*(db: PMApiDb): seq[`modelType`] =
|
proc `procName`*(db: PMApiDb): seq[`modelType`] =
|
||||||
return getRowsBy(db.conn, `modelType`)
|
return findRecordsBy(db.conn, `modelType`)
|
||||||
|
|
||||||
var callParams = quote do: @[]
|
var callParams = quote do: @[]
|
||||||
|
|
||||||
@ -125,12 +127,12 @@ macro generateProcsForFieldLookups*(modelsAndFields: openarray[tuple[t: type, fi
|
|||||||
var modelType = i[1][0]
|
var modelType = i[1][0]
|
||||||
let fieldNames = i[1][1][1].mapIt($it)
|
let fieldNames = i[1][1][1].mapIt($it)
|
||||||
|
|
||||||
let procName = ident("get" & $modelType & "By" & fieldNames.mapIt(it.capitalize).join("And"))
|
let procName = ident("find" & $modelType & "sBy" & fieldNames.mapIt(it.capitalize).join("And"))
|
||||||
|
|
||||||
# Create proc skeleton
|
# Create proc skeleton
|
||||||
let procDefAST = quote do:
|
let procDefAST = quote do:
|
||||||
proc `procName`*(db: PMApiDb): seq[`modelType`] =
|
proc `procName`*(db: PMApiDb): seq[`modelType`] =
|
||||||
return getRowsBy(db.conn, `modelType`)
|
return findRecordsBy(db.conn, `modelType`)
|
||||||
|
|
||||||
var callParams = quote do: @[]
|
var callParams = quote do: @[]
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import macros, options, sequtils, strutils, times, timeutils, unicode, uuids
|
import json, macros, options, sequtils, strutils, times, timeutils, unicode,
|
||||||
|
uuids
|
||||||
|
|
||||||
const underscoreRune = "_".toRunes[0]
|
const UNDERSCORE_RUNE = "_".toRunes[0]
|
||||||
|
const PG_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:sszz"
|
||||||
|
|
||||||
type
|
type
|
||||||
MutateClauses* = object
|
MutateClauses* = object
|
||||||
@ -23,7 +25,7 @@ proc identNameToDb*(name: string): string =
|
|||||||
if resultRunes.len == 0:
|
if resultRunes.len == 0:
|
||||||
resultRunes.add(toLower(cur))
|
resultRunes.add(toLower(cur))
|
||||||
elif isLower(prev) and isUpper(cur):
|
elif isLower(prev) and isUpper(cur):
|
||||||
resultRunes.add(underscoreRune)
|
resultRunes.add(UNDERSCORE_RUNE)
|
||||||
resultRunes.add(toLower(cur))
|
resultRunes.add(toLower(cur))
|
||||||
else: resultRunes.add(toLower(cur))
|
else: resultRunes.add(toLower(cur))
|
||||||
|
|
||||||
@ -120,7 +122,7 @@ proc createParseStmt*(t, value: NimNode): NimNode =
|
|||||||
result = quote do: parseUUID(`value`)
|
result = quote do: parseUUID(`value`)
|
||||||
|
|
||||||
elif t.getType == DateTime.getType:
|
elif t.getType == DateTime.getType:
|
||||||
result = quote do: `value`.parseIso8601
|
result = quote do: `value`.parse(PG_TIMESTAMP_FORMAT)
|
||||||
|
|
||||||
elif t.getTypeInst == Option.getType:
|
elif t.getTypeInst == Option.getType:
|
||||||
let innerType = t.getTypeImpl[2][0][0][1]
|
let innerType = t.getTypeImpl[2][0][0][1]
|
||||||
@ -132,6 +134,14 @@ proc createParseStmt*(t, value: NimNode): NimNode =
|
|||||||
else:
|
else:
|
||||||
error "Unknown value object type: " & $t.getTypeInst
|
error "Unknown value object type: " & $t.getTypeInst
|
||||||
|
|
||||||
|
elif t.typeKind == ntyRef:
|
||||||
|
|
||||||
|
if $t.getTypeInst == "JsonNode":
|
||||||
|
result = quote do: parseJson(`value`)
|
||||||
|
|
||||||
|
else:
|
||||||
|
error "Unknown ref type: " & $t.getTypeInst
|
||||||
|
|
||||||
elif t.typeKind == ntySequence:
|
elif t.typeKind == ntySequence:
|
||||||
let innerType = t[1]
|
let innerType = t[1]
|
||||||
|
|
||||||
@ -145,6 +155,9 @@ proc createParseStmt*(t, value: NimNode): NimNode =
|
|||||||
elif t.typeKind == ntyInt:
|
elif t.typeKind == ntyInt:
|
||||||
result = quote do: parseInt(`value`)
|
result = quote do: parseInt(`value`)
|
||||||
|
|
||||||
|
elif t.typeKind == ntyBool:
|
||||||
|
result = quote do: "true".startsWith(`value`.toLower)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
error "Unknown value type: " & $t.typeKind
|
error "Unknown value type: " & $t.typeKind
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user