Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions backend/src/entities/table/utils/form-full-table-structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ export function formFullTableStructure(
): Array<FullTableStructureDs> {
const { search_fields, excluded_fields } = tableSettings || {};

return structure.map(({ column_name, column_default, data_type, data_type_params, allow_null, character_maximum_length, extra }) => ({
column_name,
column_default,
data_type,
data_type_params: data_type_params || undefined,
isExcluded: excluded_fields?.includes(column_name) || false,
isSearched: search_fields?.includes(column_name) || false,
auto_increment: checkFieldAutoincrement(column_default, extra),
allow_null,
character_maximum_length,
}));
return structure.map(
({ column_name, column_default, data_type, data_type_params, allow_null, character_maximum_length, extra }) => ({
column_name,
column_default,
data_type,
data_type_params: data_type_params || undefined,
isExcluded: excluded_fields?.includes(column_name) || false,
isSearched: search_fields?.includes(column_name) || false,
auto_increment: checkFieldAutoincrement(column_default, extra),
allow_null,
character_maximum_length,
}),
);
}
52 changes: 52 additions & 0 deletions backend/test/ava-tests/saas-tests/table-postgres-e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { getTestData } from '../../utils/get-test-data.js';
import { registerUserAndReturnUserInfo } from '../../utils/register-user-and-return-user-info.js';
import { TestUtils } from '../../utils/test.utils.js';
import { WinstonLogger } from '../../../src/entities/logging/winston-logger.js';
import { getTestKnex } from '../../utils/get-test-knex.js';
import { getRandomTestTableName } from '../../utils/get-random-test-table-name.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
Expand Down Expand Up @@ -225,6 +227,56 @@ test.serial(`${currentTest} should return rows of selected table without search
}
});

test.serial(`${currentTest} should return rows of selected table with generated as identity primary key`, async (t) => {
try {
const connectionToTestDB = getTestData(mockFactory).connectionToPostgres;
const firstUserToken = (await registerUserAndReturnUserInfo(app)).token;
const testTableName = getRandomTestTableName().toLowerCase();
const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`;
const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`;

const Knex = getTestKnex(connectionToTestDB);

// await Knex.schema.dropTableIfExists(testTableName);
await Knex.schema.createTable(testTableName, (table) => {
table.integer('id').primary();
table.string(testTableColumnName);
table.string(testTableSecondColumnName);
table.timestamps();
});

await Knex.raw(`ALTER TABLE ${testTableName} ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY`);

const createConnectionResponse = await request(app.getHttpServer())
.post('/connection')
.send(connectionToTestDB)
.set('Cookie', firstUserToken)
.set('Content-Type', 'application/json')
.set('Accept', 'application/json');
const createConnectionRO = JSON.parse(createConnectionResponse.text);
t.is(createConnectionResponse.status, 201);

const getTableRowsResponse = await request(app.getHttpServer())
.get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`)
.set('Cookie', firstUserToken)
.set('Content-Type', 'application/json')
.set('Accept', 'application/json');
t.is(getTableRowsResponse.status, 200);

const getTableRowsRO = JSON.parse(getTableRowsResponse.text);
console.log('🚀 ~ getTableRowsRO:', getTableRowsRO);

t.is(typeof getTableRowsRO, 'object');
t.is(getTableRowsRO.hasOwnProperty('rows'), true);
t.is(getTableRowsRO.hasOwnProperty('primaryColumns'), true);
t.is(getTableRowsRO.hasOwnProperty('pagination'), true);
t.is(getTableRowsRO.hasOwnProperty('large_dataset'), true);
} catch (e) {
console.error(e);
throw e;
}
});

test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => {
try {
const connectionToTestDB = getTestData(mockFactory).connectionToPostgres;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,19 +350,30 @@ export class DataAccessObjectPostgres extends BasicDataAccessObject implements I
}
const knex = await this.configureKnex();
let result = await knex('information_schema.columns')
.select('column_name', 'column_default', 'data_type', 'udt_name', 'is_nullable', 'character_maximum_length')
.select(
'column_name',
'column_default',
'data_type',
'udt_name',
'is_nullable',
'character_maximum_length',
'is_identity',
'identity_generation',
)
.orderBy('dtd_identifier')
.where(`table_name`, tableName)
.andWhere('table_schema', this.connection.schema ? this.connection.schema : 'public');

const generatedIdentities: Array<string> = ['BY DEFAULT', 'ALWAYS'];
const customTypeIndexes: Array<number> = [];
result = result.map((element, i) => {
const { is_nullable, data_type } = element;
const { is_nullable, data_type, identity_generation } = element;
element.allow_null = is_nullable === 'YES';
delete element.is_nullable;
if (data_type === 'USER-DEFINED') {
customTypeIndexes.push(i);
}
element.extra = generatedIdentities.includes(identity_generation) ? 'auto_increment' : undefined;
return element;
});

Expand Down
Loading