@cloud-copilot/iam-collect
Version:
Collect IAM information from AWS Accounts
61 lines • 2.7 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeSqliteDatabases = mergeSqliteDatabases;
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
const packageVersion_js_1 = require("../config/packageVersion.js");
const SqliteAwsIamStore_js_1 = require("../persistence/sqlite/SqliteAwsIamStore.js");
/**
* Merge one or more SQLite databases (created with the same schema as SqliteAwsIamStore)
* into a single target database. If the target DB does not exist, it will be created.
*
* Does not reindex the target database.
*
* The function is safe to call repeatedly with different source sets against the
* same target. We use INSERT OR REPLACE so primary keys prevent duplication while
* allowing newer rows to overwrite older ones.
*
* @param targetPath - The path to the target SQLite database file. If this does not exist it is created.
* @param sourcePaths - An array of paths to the source SQLite database files.
*/
async function mergeSqliteDatabases(targetPath, sourcePaths) {
const TargetDB = new better_sqlite3_1.default(targetPath);
try {
const version = (0, packageVersion_js_1.iamCollectVersion)();
// Ensure the target has the required schema. This mirrors SqliteAwsIamStore.init()
const schema = SqliteAwsIamStore_js_1.SqliteAwsIamStore.schemaSql(version);
TargetDB.exec(schema);
const attach = TargetDB.prepare('ATTACH ? AS src');
const detach = TargetDB.prepare('DETACH src');
const tables = [
'resource_metadata',
'account_metadata',
'organization_metadata',
'organizational_unit_metadata',
'organization_policy_metadata',
'ram_resources'
];
for (const srcPath of sourcePaths) {
// One transaction per source file keeps memory low and performance high
const tx = TargetDB.transaction(() => {
attach.run(srcPath);
for (const t of tables) {
// Use OR REPLACE so repeated merges do not duplicate and newer data wins on PK
TargetDB.exec(`INSERT OR REPLACE INTO main.${t} SELECT * FROM src.${t}`);
}
});
try {
tx(); // execute transaction for this source
}
finally {
detach.run(); // detach outside transaction to avoid lock
}
}
}
finally {
TargetDB.close();
}
}
//# sourceMappingURL=mergeSqlite.js.map