Skip to content

Commit a68df95

Browse files
committed
fix: support ID generation on Database server. Currently PostgreSQL only. Fix for #155
1 parent 36cc51d commit a68df95

File tree

9 files changed

+66
-21
lines changed

9 files changed

+66
-21
lines changed

adminforth/dataConnectors/baseConnector.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export default class AdminForthBaseConnector implements IAdminForthDataSourceCon
7272
throw new Error('Method not implemented.');
7373
}
7474

75-
createRecordOriginalValues({ resource, record }: { resource: AdminForthResource; record: any; }): Promise<void> {
75+
createRecordOriginalValues({ resource, record }: { resource: AdminForthResource; record: any; }): Promise<string> {
7676
throw new Error('Method not implemented.');
7777
}
7878

@@ -94,9 +94,12 @@ export default class AdminForthBaseConnector implements IAdminForthDataSourceCon
9494
resource: AdminForthResource; record: any; adminUser: any;
9595
}): Promise<{ error?: string; ok: boolean; createdRecord?: any; }> {
9696
// transform value using setFieldValue and call createRecordOriginalValues
97+
9798
const filledRecord = {...record};
9899
const recordWithOriginalValues = {...record};
99100

101+
console.log('🪲🆕1', JSON.stringify(recordWithOriginalValues), JSON.stringify(Object.entries(recordWithOriginalValues)));
102+
100103
for (const col of resource.dataSourceColumns) {
101104
if (col.fillOnCreate) {
102105
if (filledRecord[col.name] === undefined) {
@@ -106,8 +109,14 @@ export default class AdminForthBaseConnector implements IAdminForthDataSourceCon
106109
});
107110
}
108111
}
109-
recordWithOriginalValues[col.name] = this.setFieldValue(col, filledRecord[col.name]);
112+
if (filledRecord[col.name] !== undefined) {
113+
// no sense to set value if it is not defined
114+
recordWithOriginalValues[col.name] = this.setFieldValue(col, filledRecord[col.name]);
115+
}
110116
}
117+
118+
console.log('🪲🆕2', JSON.stringify(recordWithOriginalValues), JSON.stringify(Object.entries(recordWithOriginalValues)));
119+
111120

112121
let error: string | null = null;
113122
await Promise.all(
@@ -125,12 +134,19 @@ export default class AdminForthBaseConnector implements IAdminForthDataSourceCon
125134
return { error, ok: false };
126135
}
127136

128-
process.env.HEAVY_DEBUG && console.log('🪲🆕 creating record', recordWithOriginalValues);
129-
await this.createRecordOriginalValues({ resource, record: recordWithOriginalValues });
137+
console.log('🪲🆕2', JSON.stringify(recordWithOriginalValues), JSON.stringify(Object.entries(recordWithOriginalValues)));
138+
139+
process.env.HEAVY_DEBUG && console.log('🪲🆕 creating record',JSON.stringify(recordWithOriginalValues));
140+
const pkValue = await this.createRecordOriginalValues({ resource, record: recordWithOriginalValues });
141+
142+
let createdRecord = recordWithOriginalValues;
143+
if (pkValue) {
144+
createdRecord = await this.getRecordByPrimaryKey(resource, pkValue);
145+
}
130146

131147
return {
132148
ok: true,
133-
createdRecord: recordWithOriginalValues,
149+
createdRecord,
134150
}
135151
}
136152

adminforth/dataConnectors/clickhouse.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ class ClickhouseConnector extends AdminForthBaseConnector implements IAdminForth
294294
}))
295295
return result;
296296
}
297-
async createRecordOriginalValues({ resource, record }: { resource: AdminForthResource, record: any }) {
297+
async createRecordOriginalValues({ resource, record }: { resource: AdminForthResource, record: any }): Promise<string> {
298298
const tableName = resource.table;
299299
const columns = Object.keys(record);
300300
await this.client.insert({
@@ -303,6 +303,7 @@ class ClickhouseConnector extends AdminForthBaseConnector implements IAdminForth
303303
columns: columns,
304304
values: [Object.values(record)],
305305
});
306+
return ''; // todo
306307
}
307308

308309
async updateRecordOriginalValues({ resource, recordId, newValues }: { resource: AdminForthResource, recordId: any, newValues: any }) {

adminforth/dataConnectors/mongo.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
174174
return result;
175175
}
176176

177-
async createRecordOriginalValues({ resource, record }) {
177+
async createRecordOriginalValues({ resource, record }): Promise<string> {
178178
const tableName = resource.table;
179179
const collection = this.client.db().collection(tableName);
180180
const columns = Object.keys(record);
@@ -183,6 +183,7 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
183183
newRecord[colName] = record[colName];
184184
}
185185
await collection.insertOne(newRecord);
186+
return ''; // todo
186187
}
187188

188189
async updateRecordOriginalValues({ resource, recordId, newValues }) {

adminforth/dataConnectors/mysql.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ class MysqlConnector extends AdminForthBaseConnector implements IAdminForthDataS
257257
return result;
258258
}
259259

260-
async createRecordOriginalValues({ resource, record }) {
260+
async createRecordOriginalValues({ resource, record }): Promise<string> {
261261
const tableName = resource.table;
262262
const columns = Object.keys(record);
263263
const placeholders = columns.map(() => '?').join(', ');
@@ -267,6 +267,8 @@ class MysqlConnector extends AdminForthBaseConnector implements IAdminForthDataS
267267
console.log('🪲📜 MySQL Q:', q, 'values:', values);
268268
}
269269
await this.client.execute(q, values);
270+
271+
return ''; // todo
270272
}
271273

272274
async updateRecordOriginalValues({ resource, recordId, newValues }) {

adminforth/dataConnectors/postgres.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,19 +302,21 @@ class PostgresConnector extends AdminForthBaseConnector implements IAdminForthDa
302302
return result;
303303
}
304304

305-
async createRecordOriginalValues({ resource, record }) {
305+
async createRecordOriginalValues({ resource, record }): Promise<string> {
306306
const tableName = resource.table;
307307
const columns = Object.keys(record);
308308
const placeholders = columns.map((_, i) => `$${i + 1}`).join(', ');
309309
const values = columns.map((colName) => record[colName]);
310310
for (let i = 0; i < columns.length; i++) {
311311
columns[i] = `"${columns[i]}"`;
312312
}
313-
const q = `INSERT INTO "${tableName}" (${columns.join(', ')}) VALUES (${placeholders})`;
313+
const primaryKey = this.getPrimaryKey(resource);
314+
const q = `INSERT INTO "${tableName}" (${columns.join(', ')}) VALUES (${placeholders}) RETURNING "${primaryKey}"`;
314315
if (process.env.HEAVY_DEBUG_QUERY) {
315316
console.log('🪲📜 PG Q:', q, 'values:', values);
316317
}
317-
await this.client.query(q, values);
318+
const ret = await this.client.query(q, values);
319+
return ret.rows[0][primaryKey];
318320
}
319321

320322
async updateRecordOriginalValues({ resource, recordId, newValues }) {

adminforth/types/Back.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,9 @@ export interface IAdminForthDataSourceConnector {
206206

207207

208208
/**
209-
* Used to create record in database.
209+
* Used to create record in database. Should return value of primary key column of created record.
210210
*/
211-
createRecordOriginalValues({ resource, record }: { resource: AdminForthResource, record: any }): Promise<void>;
211+
createRecordOriginalValues({ resource, record }: { resource: AdminForthResource, record: any }): Promise<string>;
212212

213213
/**
214214
* Update record in database. newValues might have not all fields in record, but only changed ones.

dev-demo/index.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import clinicsResource from './resources/clinics.js';
1717
import providersResource from './resources/providers.js';
1818
import apiKeysResource from './resources/api_keys.js';
1919
import CompletionAdapterOpenAIChatGPT from '../adapters/adminforth-completion-adapter-open-ai-chat-gpt/index.js';
20+
import pkg from 'pg';
21+
const { Client } = pkg;
2022

2123
// const ADMIN_BASE_URL = '/portal';
2224
const ADMIN_BASE_URL = '';
@@ -182,10 +184,10 @@ export const admin = new AdminForth({
182184
id: 'maindb',
183185
url: `sqlite://${dbPath}`
184186
},
185-
// {
186-
// id: 'db2',
187-
// url: 'postgres://postgres:[email protected]:5432'
188-
// },
187+
{
188+
id: 'pg',
189+
url: 'postgres://demo:demo@localhost:53321/demo',
190+
},
189191
{
190192
id: 'db3',
191193
url: 'mongodb://127.0.0.1:27028/demo?retryWrites=true&w=majority&authSource=admin',
@@ -477,7 +479,22 @@ app.get(`${ADMIN_BASE_URL}/api/aparts-by-room-percentages/`,
477479

478480

479481
// serve after you added all api
480-
admin.express.serve(app)
482+
admin.express.serve(app);
483+
484+
485+
(async function () {
486+
const c = new Client({
487+
connectionString: 'postgres://demo:demo@localhost:53321/demo',
488+
});
489+
await c.connect();
490+
await c.query(
491+
`CREATE TABLE IF NOT EXISTS clinics (
492+
id SERIAL PRIMARY KEY,
493+
name VARCHAR(255) NOT NULL
494+
);`
495+
);
496+
})();
497+
481498
admin.discoverDatabases().then(async () => {
482499
console.log('🅿️ Database discovered');
483500

@@ -489,6 +506,11 @@ admin.discoverDatabases().then(async () => {
489506
});
490507
}
491508
await seedDatabase();
509+
510+
// create table clinics in postgress,
511+
// id Int @id @db.SmallInt @default(autoincrement())
512+
// name String @db.VarChar(255)
513+
492514
});
493515

494516
admin.express.listen(port, () => {

dev-demo/inventory.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ services:
2424
image: postgres:13
2525
restart: always
2626
ports:
27-
- "54321:5432"
27+
- "53321:5432"
2828
environment:
2929
POSTGRES_USER: demo
3030
POSTGRES_PASSWORD: demo

dev-demo/resources/clinics.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { AdminForthDataTypes, AdminForthResourceInput } from "../../adminforth";
22
import { v1 as uuid } from "uuid";
33

44
export default {
5-
dataSource: 'maindb',
5+
dataSource: 'pg',
66
table: 'clinics',
77
resourceId: 'clinics',
88
label: 'Clinics',
@@ -12,7 +12,7 @@ export default {
1212
name: 'id',
1313
label: 'ID',
1414
primaryKey: true,
15-
fillOnCreate: ({ initialRecord, adminUser }: any) => uuid(),
15+
// fillOnCreate: ({ initialRecord, adminUser }: any) => uuid(),
1616
showIn: {
1717
create: false,
1818
edit: false,
@@ -27,6 +27,7 @@ export default {
2727
required: true,
2828
maxLength: 255,
2929
},
30+
3031
],
3132
plugins: [],
3233
options: {},

0 commit comments

Comments
 (0)