This commit is contained in:
728
2023-05-20 11:14:01 +08:00
parent f4e3b0e034
commit 68f408fde3
3 changed files with 127 additions and 47 deletions

View File

@ -1,17 +1,59 @@
import { Collection, IndexOptions, MongoClient, UpdateFilter, Document } from "./mod.ts"
import { Act, Agd, Aut, Dst, Lit, Ord, Soc, Usr, Video, Work, Wsl } from "./typ.ts"
export type Coll<T extends Document> = Collection<T>
export type Proj<T, P extends keyof T> = Partial<{ [K in P]: 0 } | { [K in P]: 1 }>
export type Update<T> = UpdateFilter<T>
export type DocC<_Id> = Promise<NonNullable<_Id> | null>
export type DocR<Doc> = Promise<NonNullable<Doc> | null>
export type DocU = Promise<0 | 1 | null>
export type DocD = Promise<0 | 1 | null>
const conn = new MongoClient()
await conn.connect("mongodb://127.0.0.1:27017")
export let coll = await db("tst", true)
export type Coll<T extends Document> = Collection<T>
export type Update<T> = UpdateFilter<T>
export type DocC<_Id> = Promise<NonNullable<_Id> | null>
export type DocR<Doc> = Promise<NonNullable<Doc> | null>
export type DocU = Promise<0 | 1 | null>
export type DocD = Promise<0 | 1 | null>
export async function db(
dbnam: "ismism-dev" | "tst",
reset = false,
) {
const db = conn.database(dbnam)
const c = {
usr: db.collection<Usr>("usr"),
agd: db.collection<Agd>("agd"),
soc: db.collection<Soc>("soc"),
work: db.collection<Work>("work"),
video: db.collection<Video>("video"),
ord: db.collection<Ord>("ord"),
dst: db.collection<Dst>("dst"),
wsl: db.collection<Wsl>("wsl"),
lit: db.collection<Lit>("lit"),
aut: db.collection<Aut>("aut"),
act: db.collection<Act>("act"),
}
if (reset) {
await db.dropDatabase()
await c.usr.createIndexes({ indexes: [...nam, ...nbr, ...re] })
await c.agd.createIndexes({ indexes: [...nam, ...adm, ...re, ...rel] })
await c.soc.createIndexes({ indexes: [...nam, ...adm, ...re, ...rel] })
await c.work.createIndexes({ indexes: [...rec] })
await c.video.createIndexes({ indexes: [...rec, ...live] })
await c.ord.createIndexes({ indexes: [...rec] })
await c.dst.createIndexes({ indexes: [...dst] })
await c.wsl.createIndexes({ indexes: [...md] })
await c.lit.createIndexes({ indexes: [...md] })
}
if (dbnam === "ismism-dev") coll = c
return c
}
const nam: IndexOptions[] = [{
key: { nam: 1 }, name: "nam", unique: true,
@ -58,44 +100,3 @@ const md: IndexOptions[] = [{
key: { pin: 1, "utc.put": -1 }, name: "pin",
partialFilterExpression: { pin: { $exists: true } }
}]
export async function db(
dbnam: "ismism-dev" | "tst",
reset = false,
) {
const db = conn.database(dbnam)
const c = {
usr: db.collection<Usr>("usr"),
agd: db.collection<Agd>("agd"),
soc: db.collection<Soc>("soc"),
work: db.collection<Work>("work"),
video: db.collection<Video>("video"),
ord: db.collection<Ord>("ord"),
dst: db.collection<Dst>("dst"),
wsl: db.collection<Wsl>("wsl"),
lit: db.collection<Lit>("lit"),
aut: db.collection<Aut>("aut"),
act: db.collection<Act>("act"),
}
if (reset) {
await db.dropDatabase()
await c.usr.createIndexes({ indexes: [...nam, ...nbr, ...re] })
await c.agd.createIndexes({ indexes: [...nam, ...adm, ...re, ...rel] })
await c.soc.createIndexes({ indexes: [...nam, ...adm, ...re, ...rel] })
await c.work.createIndexes({ indexes: [...rec] })
await c.video.createIndexes({ indexes: [...rec, ...live] })
await c.ord.createIndexes({ indexes: [...rec] })
await c.dst.createIndexes({ indexes: [...dst] })
await c.wsl.createIndexes({ indexes: [...md] })
await c.lit.createIndexes({ indexes: [...md] })
}
if (dbnam === "ismism-dev") coll = c
return c
}

74
ismism.ts/src/eid/id.ts Normal file
View File

@ -0,0 +1,74 @@
import type { Id } from "./typ.ts"
import type { Coll, DocC, DocD, DocR, DocU, Proj, Update } from "./db.ts"
import { is_id, is_intro, is_nam, is_utc } from "./is.ts"
import { is_adm } from "../ont/adm.ts"
export async function id_n<
T extends Id
>(
c: Coll<T>
): Promise<T["_id"]> {
const l = await c.findOne({}, { projection: { _id: 1 }, sort: { _id: -1 } })
return l ? l._id + 1 : 1
}
export async function id_c<
T extends Id
>(
c: Coll<T>,
id: T,
): DocC<T["_id"]> {
const is = is_id(id._id)
&& is_utc(id.utc)
&& (is_nam(id.nam) || id.nam === `${id._id}`)
&& is_adm(id.adm1, id.adm2)
&& is_intro(id.intro)
if (!is) return null
try { return await c.insertOne(id) as T["_id"] } catch { return null }
}
export async function id_r<
T extends Id,
P extends keyof T,
>(
c: Coll<T>,
f: Partial<T>,
p: Proj<T, P>,
): DocR<Pick<T, "_id" | P>> {
if (f._id && !is_id(f._id) || f.nam && !is_nam(f.nam)) return null
return await c.findOne(f, { projection: p }) ?? null
}
export async function id_u<
T extends Id
>(
c: Coll<T>,
_id: T["_id"],
u: Update<T>,
): DocU {
if (!is_id(_id)) return null
const s = u["$set"]
if (s) {
if (s.nam && !is_nam(s.nam)) return null
if ((s.adm1 || s.adm2) && !((s.adm1 && s.adm2) && is_adm(s.adm1, s.adm2))) return null
if (s.intro && !is_intro(s.intro)) return null
}
try { // deno-lint-ignore no-explicit-any
const { matchedCount, modifiedCount } = await c.updateOne({ _id } as any, u)
if (matchedCount > 0) return modifiedCount > 0 ? 1 : 0
else return null
} catch { return null }
}
export async function id_d<
T extends Id
>(
c: Coll<T>,
_id: T["_id"],
): DocD {
if (!is_id(_id)) return null
try { // deno-lint-ignore no-explicit-any
const d = await c.deleteOne({ _id } as any)
return d > 0 ? 1 : 0
} catch { return null }
}

View File

@ -50,6 +50,11 @@ export function is_idl(
) {
return id.length <= lim && id.every(is_id)
}
export function is_utc(
utc: number
) {
return Number.isInteger(utc)
}
export function is_nam(
nam: string
) {