@sugarcube/plugin-sql
Version:
Import and export Sugarcube data and queries from and to SQL databases.
329 lines (298 loc) • 7.35 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _fp = require("lodash/fp");
var _core = require("@sugarcube/core");
// The queries export handles the concatenation of two relations list as well.
class Units {
constructor(db, queries, {
queriesStore
}) {
this.db = db;
this.queries = queries;
this.queriesStore = queriesStore;
}
async create(u) {
const insertUnit = this.db.transaction(unit => {
const {
id,
existing
} = this.selectOrInsertUnitSync(unit);
const downloads = _core.queries.concat(this.listDownloadsSync(id), unit._sc_downloads);
const media = _core.queries.concat(this.listMediaSync(id), unit._sc_media);
this.createDownloadsSync(downloads, id);
this.createMediaSync(media, id);
this.createQueriesSync(unit._sc_queries, id);
this.createTagsSync(unit._sc_tags, id);
this.appendToRunSync(unit._sc_markers, id);
return existing;
});
return insertUnit(u);
}
async listAll() {
const {
listAllQuery
} = this.queries;
const stmt = this.db.prepare(listAllQuery);
const units = stmt.all();
for (let i = 0; i < units.length; i += 1) {
const {
id,
id_hash: idHash,
id_fields: idFields,
content_fields: contentFields,
data: rest,
...unit
} = units[i];
const downloads = this.listDownloadsSync(id);
const media = this.listMediaSync(id);
const queries = this.listQueriesSync(id);
const tags = this.listTagsSync(id);
const markers = this.listMarkersSync(id);
units[i] = {
_sc_id_hash: idHash,
_sc_id_fields: JSON.parse(idFields),
_sc_content_fields: contentFields ? JSON.parse(contentFields) : undefined,
_sc_data: JSON.parse(rest),
_sc_media: media,
_sc_downloads: downloads,
_sc_queries: queries,
_sc_tags: tags,
_sc_markers: markers,
// filter null values map names to _sc naming scheme
...Object.keys(unit).reduce((memo, key) => {
const value = units[i][key];
if (value == null) return memo;
return {
[`_sc_${key}`]: value,
...memo
};
}, {})
};
}
return units;
}
selectOrInsertUnitSync({
_sc_id_hash: idHash,
_sc_id_fields: idFields,
_sc_content_hash: contentHash,
_sc_content_fields: contentFields,
_sc_source: source,
_sc_unit_id: unitId,
_sc_body: body,
_sc_href: href,
_sc_author: author,
_sc_title: title,
_sc_description: description,
_sc_language: language,
_sc_pubdates: dates,
_sc_data: rest
}) {
const {
showQuery,
createQuery
} = this.queries;
const stmt = this.db.prepare(showQuery);
const stmt2 = this.db.prepare(createQuery);
const unit = stmt.get({
idHash
});
if (unit) return {
id: unit.id,
existing: true
};
const createdAt = (0, _fp.get)("source", dates) ? (0, _fp.get)("source", dates).toISOString() : undefined;
const fetchedAt = (0, _fp.get)("fetch", dates) ? (0, _fp.get)("fetch", dates).toISOString() : undefined;
const {
lastInsertRowid
} = stmt2.run({
idHash,
idFields: JSON.stringify(idFields),
contentHash,
contentFields: contentFields ? JSON.stringify(contentFields) : "[]",
source,
unitId,
body,
href,
author,
title,
description,
language,
createdAt,
fetchedAt,
data: JSON.stringify(rest)
});
return {
id: lastInsertRowid,
existing: false
};
}
listQueriesSync(unitId) {
const {
listQueriesQuery
} = this.queries;
const stmt = this.db.prepare(listQueriesQuery);
return stmt.all({
unitId
});
}
listTagsSync(unitId) {
const {
listTagsQuery
} = this.queries;
const stmt = this.db.prepare(listTagsQuery);
return stmt.all({
unitId
});
}
listDownloadsSync(unitId) {
const {
listDownloadsQuery
} = this.queries;
return this.listRelationsSync(listDownloadsQuery, unitId);
}
listMediaSync(unitId) {
const {
listMediaQuery
} = this.queries;
return this.listRelationsSync(listMediaQuery, unitId);
}
listMarkersSync(unitId) {
const {
listMarkersQuery
} = this.queries;
const stmt = this.db.prepare(listMarkersQuery);
return stmt.all({
unitId
}).map(({
marker
}) => marker);
}
listRelationsSync(query, unitId) {
const stmt = this.db.prepare(query);
const relations = stmt.all({
unitId
});
return relations.map(({
id_hash: idHash,
data: rest,
...relation
}) => ({
_sc_id_hash: idHash,
...JSON.parse(rest),
...relation
}));
}
selectOrInsertMarkerSync(marker) {
const {
showMarkerQuery,
createMarkerQuery
} = this.queries;
const stmt = this.db.prepare(showMarkerQuery);
const stmt2 = this.db.prepare(createMarkerQuery);
const markerId = stmt.get({
marker
});
if (markerId != null) return markerId.id;
const {
lastInsertRowid
} = stmt2.run({
marker
});
return lastInsertRowid;
}
createDownloadsSync(downloads, unitId) {
const {
createDownloadsQuery
} = this.queries;
const stmt = this.db.prepare(createDownloadsQuery);
for (const {
_sc_id_hash: idHash,
type,
term,
md5,
sha256,
location,
...rest
} of downloads) {
stmt.run({
idHash,
type,
term,
md5,
sha256,
location,
data: JSON.stringify(rest),
unit: unitId
});
}
}
createMediaSync(media, unitId) {
const {
createMediaQuery
} = this.queries;
const stmt = this.db.prepare(createMediaQuery);
for (const {
_sc_id_hash: idHash,
type,
term,
...rest
} of media) {
stmt.run({
idHash,
type,
term,
data: JSON.stringify(rest),
unit: unitId
});
}
}
createQueriesSync(queries, unitId) {
const {
createQueryResultQuery
} = this.queries;
const stmt = this.db.prepare(createQueryResultQuery);
for (const {
type,
term
} of queries) {
const query = this.queriesStore.selectOrInsertSync(type, term);
stmt.run({
query,
unit: unitId
});
}
}
createTagsSync(tags, unitId) {
const {
createTaggedUnitQuery
} = this.queries;
const stmt = this.db.prepare(createTaggedUnitQuery);
for (const {
label
} of tags) {
const queryTag = this.queriesStore.showQueryTagSync(label);
if (queryTag) stmt.run({
queryTag: queryTag.id,
unit: unitId
});
}
}
appendToRunSync(markers, unitId) {
const {
createRunQuery
} = this.queries;
const stmt = this.db.prepare(createRunQuery);
for (const marker of markers) {
const markerId = this.selectOrInsertMarkerSync(marker);
stmt.run({
marker: markerId,
unit: unitId
});
}
}
}
var _default = Units;
exports.default = _default;