| 130 | return { |
| 131 | name: "memory", |
| 132 | createORM(schema): AbstractQuery<AnySchema> { |
| 133 | let orm: AbstractQuery<AnySchema>; |
| 134 | orm = toORM({ |
| 135 | tables: schema.tables, |
| 136 | async count(table, v) { |
| 137 | return tableRows(db, table).filter((row) => matchesCondition(row, v.where)).length; |
| 138 | }, |
| 139 | async findFirst(table, v) { |
| 140 | return (await this.findMany(table, { ...v, limit: 1 }))[0] ?? null; |
| 141 | }, |
| 142 | async findMany(table, v) { |
| 143 | if (v.join?.length) throw new Error("[FumaDB Memory] Joins are not supported."); |
| 144 | let rows = tableRows(db, table).filter((row) => matchesCondition(row, v.where)); |
| 145 | |
| 146 | for (const [column, direction] of [...(v.orderBy ?? [])].reverse()) { |
| 147 | rows = [...rows].sort((a, b) => { |
| 148 | const left = comparable(columnValue(a, column)); |
| 149 | const right = comparable(columnValue(b, column)); |
| 150 | if (left == null && right == null) return 0; |
| 151 | if (left == null) return direction === "asc" ? -1 : 1; |
| 152 | if (right == null) return direction === "asc" ? 1 : -1; |
| 153 | if (left < right) return direction === "asc" ? -1 : 1; |
| 154 | if (left > right) return direction === "asc" ? 1 : -1; |
| 155 | return 0; |
| 156 | }); |
| 157 | } |
| 158 | |
| 159 | const offset = v.offset ?? 0; |
| 160 | const limited = rows.slice(offset, v.limit === undefined ? undefined : offset + v.limit); |
| 161 | return limited.map((row) => selectRow(table, row, v.select)); |
| 162 | }, |
| 163 | async updateMany(table, v) { |
| 164 | for (const row of tableRows(db, table)) { |
| 165 | if (!matchesCondition(row, v.where)) continue; |
| 166 | Object.assign(row, cloneValue(v.set)); |
| 167 | } |
| 168 | }, |
| 169 | async upsert(table, v) { |
| 170 | const existing = tableRows(db, table).find((row) => matchesCondition(row, v.where)); |
| 171 | if (existing) { |
| 172 | Object.assign(existing, cloneValue(v.update)); |
| 173 | return; |
| 174 | } |
| 175 | await this.create(table, v.create); |
| 176 | }, |
| 177 | async create(table, values) { |
| 178 | const row = applyDefaults(table, values); |
| 179 | tableRows(db, table).push(row); |
| 180 | return cloneValue(row); |
| 181 | }, |
| 182 | async createMany(table, values) { |
| 183 | const idColumn = table.getIdColumn(); |
| 184 | return Promise.all(values.map((value) => this.create(table, value))).then((rows) => |
| 185 | rows.map((row) => ({ _id: row[idColumn.ormName] })) |
| 186 | ); |
| 187 | }, |
| 188 | async deleteMany(table, v) { |
| 189 | const rows = tableRows(db, table); |