Skip to content

Commit

Permalink
HCK-8697: Improve RE of partitions (#88)
Browse files Browse the repository at this point in the history
* HCK-8697: added improed query draft

* Created module for reusable query

* Added missing line break

* Applied reusable nested query

* Added missing argument

* Fixed formatting

* Fixed formatting

* Fixed formatting

* HCK-8697: handle no items selection case

---------

Co-authored-by: Thomas Jakemeyn <thomas.jakemeyn@gmail.com>
  • Loading branch information
WilhelmWesser and thomas-jakemeyn authored Nov 8, 2024
1 parent 11c81f8 commit df0a482
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 16 deletions.
32 changes: 17 additions & 15 deletions reverse_engineering/databaseService/databaseService.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const { getObjectsFromDatabase, getNewConnectionClientByDb } = require('./helper
const getSampleDocSize = require('../helpers/getSampleDocSize');
const { logAuthTokenInfo } = require('../helpers/logInfo');
const { getConnection } = require('./helpers/connection');
const {
queryForRetrievingTheTablesSelectedByTheUser,
} = require('../queries/queryForRetrievingTheTablesSelectedByTheUser');

const QUERY_REQUEST_TIMEOUT = 60000;

Expand Down Expand Up @@ -253,32 +256,31 @@ const getViewsIndexes = async (connectionClient, dbName) => {
);
};

const getPartitions = async (connectionClient, dbName, logger) => {
const currentDbConnectionClient = await getNewConnectionClientByDb(connectionClient, dbName);

const getPartitions = async ({ connectionClient, tablesInfo, dbName, logger }) => {
logger.log('info', { message: `Get '${dbName}' database partitions.` }, 'Reverse Engineering');

return mapResponse(
await currentDbConnectionClient.query`
SELECT
sch.name AS schemaName,
tbl.name AS tableName,
const currentDbConnectionClient = await getNewConnectionClientByDb(connectionClient, dbName);
const tablesSelectedByTheUser = queryForRetrievingTheTablesSelectedByTheUser({ schemaToTablesMap: tablesInfo });
const queryForRetrievingThePartitions = `
WITH user_selected_tables AS (${tablesSelectedByTheUser.sql()})
SELECT
tbl.${tablesSelectedByTheUser.projection.schemaName} AS schemaName,
tbl.${tablesSelectedByTheUser.projection.tableName} AS tableName,
prt.partition_number,
pf.boundary_value_on_right AS range,
c.name AS name,
rng.value AS value
FROM sys.schemas sch
INNER JOIN sys.tables tbl ON sch.schema_id = tbl.schema_id
INNER JOIN sys.partitions prt ON prt.object_id = tbl.object_id
FROM user_selected_tables tbl
INNER JOIN sys.partitions prt ON prt.object_id = tbl.${tablesSelectedByTheUser.projection.tableId}
INNER JOIN sys.indexes idx ON prt.object_id = idx.object_id AND prt.index_id = idx.index_id
INNER JOIN sys.data_spaces ds ON idx.data_space_id = ds.[data_space_id]
INNER JOIN sys.partition_schemes ps ON ds.data_space_id = ps.data_space_id
INNER JOIN sys.partition_functions pf ON ps.function_id = pf.function_id
INNER JOIN sys.index_columns ic ON ic.object_id = idx.object_id AND ic.index_id = idx.index_id AND ic.partition_ordinal >= 1
INNER JOIN sys.columns c ON tbl.object_id = c.object_id AND ic.column_id = c.column_id
INNER JOIN sys.columns c ON tbl.${tablesSelectedByTheUser.projection.tableId} = c.object_id AND ic.column_id = c.column_id
LEFT JOIN sys.partition_range_values rng ON pf.function_id = rng.function_id AND rng.boundary_id = prt.partition_number
`,
);
`;

return mapResponse(await currentDbConnectionClient.query(queryForRetrievingThePartitions));
};

const getTableColumnsDescription = async (connectionClient, dbName, tableName, schemaName) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
function buildPredicateForTable({ schema, table }) {
return `(sch.name = '${schema}' AND tbl.name = '${table}')`;
}

function buildPredicateForTablesInSchema({ schema, tables }) {
return tables.map(table => buildPredicateForTable({ schema, table })).join('OR');
}

function queryForRetrievingTheTablesSelectedByTheUser({ schemaToTablesMap }) {
const projection = {
tableId: 'tableId',
tableName: 'tableName',
schemaName: 'schemaName',
};
const predicate = Object.entries(schemaToTablesMap)
.map(([schema, tables]) => buildPredicateForTablesInSchema({ schema, tables }))
.join('OR');
const whereClause = Object.entries(schemaToTablesMap).length > 0 ? `WHERE ${predicate}` : '';
const sql = `
SELECT
tbl.object_id AS ${projection.tableId}
, tbl.name AS ${projection.tableName}
, sch.name AS ${projection.schemaName}
FROM sys.tables tbl
JOIN sys.schemas sch ON sch.schema_id = tbl.schema_id
${whereClause}`;
return {
projection,
sql: () => sql,
};
}

module.exports = { queryForRetrievingTheTablesSelectedByTheUser };
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,9 @@ const reverseCollectionsToJSON = logger => async (dbConnectionClient, tablesInfo
getDatabaseUserDefinedTypes(dbConnectionClient, dbName, logger).catch(
logError(logger, 'Getting user defined types'),
),
getPartitions(dbConnectionClient, dbName, logger),
getPartitions({ connectionClient: dbConnectionClient, tablesInfo, dbName, logger }).catch(
logError(logger, 'Getting partitions'),
),
]);

return await Object.entries(tablesInfo).reduce(async (jsonSchemas, [schemaName, tableNames]) => {
Expand Down

0 comments on commit df0a482

Please sign in to comment.