| 117 | } |
| 118 | |
| 119 | public async update(model: Model, attributes: Partial<ValidAttributes>): Promise<Model> { |
| 120 | return this.database.sequence(async (sequenceDb: DatabaseInterface): Promise<Model> => { |
| 121 | const fieldQueries = Object.entries(attributes).map( |
| 122 | ([key, value]: [string, any]) => ( |
| 123 | sql`${new QueryIdentifier(key)} = ${value}` |
| 124 | ) |
| 125 | ); |
| 126 | |
| 127 | let results = await sequenceDb.updateAndGet(sql` |
| 128 | UPDATE ${new QueryIdentifier(this.table)} |
| 129 | SET ${SqlQuery.join(fieldQueries, sql`, `)} |
| 130 | WHERE ${new QueryIdentifier(this.primaryKey)} = ${(<any>model)[this.primaryKey]} |
| 131 | `); |
| 132 | |
| 133 | if (results === null) { |
| 134 | results = await sequenceDb.query(sql` |
| 135 | SELECT * |
| 136 | FROM ${new QueryIdentifier(this.table)} |
| 137 | WHERE ${new QueryIdentifier(this.primaryKey)} = ${(<any>model)[this.primaryKey]}; |
| 138 | `); |
| 139 | |
| 140 | if (results.length === 0) { |
| 141 | throw new NotFoundError(`Object not found in table ${this.table} after update (got ${this.primaryKey} = ${(<any>model)[this.primaryKey]})`); |
| 142 | } |
| 143 | } else { |
| 144 | if (results.length === 0) { |
| 145 | throw new NotFoundError(`Object not found in table ${this.table} for ${this.primaryKey} = ${(<any>model)[this.primaryKey]}`); |
| 146 | } |
| 147 | if (results.length > 1) { |
| 148 | throw new TooManyResultsError(`Multiple objects found in table ${this.table} for ${this.primaryKey} = ${(<any>model)[this.primaryKey]}`); |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | const newModel = await this.createModelFromAttributes(model); |
| 153 | Object.assign(newModel, results[0]); |
| 154 | return newModel; |
| 155 | }); |
| 156 | } |
| 157 | |
| 158 | public async delete(model: Model) { |
| 159 | await this.database.query(sql` |