mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-19 14:13:34 +01:00
ImportEtherpad: Use a real ueberdb object for the temp Pad
Now plugin authors have access to the full set of DB operations.
This commit is contained in:
parent
6a183db850
commit
10117bc988
1 changed files with 48 additions and 54 deletions
|
@ -24,6 +24,7 @@ const db = require('../db/DB');
|
|||
const hooks = require('../../static/js/pluginfw/hooks');
|
||||
const log4js = require('log4js');
|
||||
const supportedElems = require('../../static/js/contentcollector').supportedElems;
|
||||
const ueberdb = require('ueberdb2');
|
||||
|
||||
const logger = log4js.getLogger('ImportEtherpad');
|
||||
|
||||
|
@ -55,66 +56,59 @@ exports.setPadRaw = async (padId, r, authorId = '') => {
|
|||
// First validate and transform values. Do not commit any records to the database yet in case
|
||||
// there is a problem with the data.
|
||||
|
||||
const dbRecords = new Map();
|
||||
const data = new Map();
|
||||
const existingAuthors = new Set();
|
||||
await Promise.all(Object.entries(records).map(([key, value]) => q.pushAsync(async () => {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
const keyParts = key.split(':');
|
||||
const [prefix, id] = keyParts;
|
||||
if (prefix === 'globalAuthor' && keyParts.length === 2) {
|
||||
// In the database, the padIDs subkey is an object (which is used as a set) that records every
|
||||
// pad the author has worked on. When exported, that object becomes a single string containing
|
||||
// the exported pad's ID.
|
||||
if (typeof value.padIDs !== 'string') {
|
||||
throw new TypeError('globalAuthor padIDs subkey is not a string');
|
||||
}
|
||||
checkOriginalPadId(value.padIDs);
|
||||
if (await authorManager.doesAuthorExist(id)) {
|
||||
existingAuthors.add(id);
|
||||
const padDb = new ueberdb.Database('memory', {data});
|
||||
await padDb.init();
|
||||
try {
|
||||
await Promise.all(Object.entries(records).map(([key, value]) => q.pushAsync(async () => {
|
||||
if (!value) return;
|
||||
const keyParts = key.split(':');
|
||||
const [prefix, id] = keyParts;
|
||||
if (prefix === 'globalAuthor' && keyParts.length === 2) {
|
||||
// In the database, the padIDs subkey is an object (which is used as a set) that records
|
||||
// every pad the author has worked on. When exported, that object becomes a single string
|
||||
// containing the exported pad's ID.
|
||||
if (typeof value.padIDs !== 'string') {
|
||||
throw new TypeError('globalAuthor padIDs subkey is not a string');
|
||||
}
|
||||
checkOriginalPadId(value.padIDs);
|
||||
if (await authorManager.doesAuthorExist(id)) {
|
||||
existingAuthors.add(id);
|
||||
return;
|
||||
}
|
||||
value.padIDs = {[padId]: 1};
|
||||
} else if (padKeyPrefixes.includes(prefix)) {
|
||||
checkOriginalPadId(id);
|
||||
if (prefix === 'pad' && keyParts.length === 2) {
|
||||
const pool = new AttributePool().fromJsonable(value.pool);
|
||||
const unsupportedElements = new Set();
|
||||
pool.eachAttrib((k, v) => {
|
||||
if (!supportedElems.has(k)) unsupportedElements.add(k);
|
||||
});
|
||||
if (unsupportedElements.size) {
|
||||
logger.warn(`(pad ${padId}) unsupported attributes (try installing a plugin): ` +
|
||||
`${[...unsupportedElements].join(', ')}`);
|
||||
}
|
||||
}
|
||||
keyParts[1] = padId;
|
||||
key = keyParts.join(':');
|
||||
} else {
|
||||
logger.warn(`(pad ${padId}) Ignoring record with unsupported key: ${key}`);
|
||||
return;
|
||||
}
|
||||
value.padIDs = {[padId]: 1};
|
||||
} else if (padKeyPrefixes.includes(prefix)) {
|
||||
checkOriginalPadId(id);
|
||||
if (prefix === 'pad' && keyParts.length === 2) {
|
||||
const pool = new AttributePool().fromJsonable(value.pool);
|
||||
const unsupportedElements = new Set();
|
||||
pool.eachAttrib((k, v) => {
|
||||
if (!supportedElems.has(k)) unsupportedElements.add(k);
|
||||
});
|
||||
if (unsupportedElements.size) {
|
||||
logger.warn(`(pad ${padId}) unsupported attributes (try installing a plugin): ` +
|
||||
`${[...unsupportedElements].join(', ')}`);
|
||||
}
|
||||
}
|
||||
keyParts[1] = padId;
|
||||
key = keyParts.join(':');
|
||||
} else {
|
||||
logger.warn(`(pad ${padId}) Ignoring record with unsupported key: ${key}`);
|
||||
return;
|
||||
}
|
||||
dbRecords.set(key, value);
|
||||
})));
|
||||
await padDb.set(key, value);
|
||||
})));
|
||||
|
||||
const pad = new Pad(padId, {
|
||||
// Only fetchers are needed to check the pad's integrity.
|
||||
get: async (k) => dbRecords.get(k),
|
||||
getSub: async (k, sub) => {
|
||||
let v = dbRecords.get(k);
|
||||
for (const sk of sub) {
|
||||
if (v == null) return null;
|
||||
v = v[sk];
|
||||
}
|
||||
return v;
|
||||
},
|
||||
});
|
||||
await pad.init(null, authorId);
|
||||
await pad.check();
|
||||
const pad = new Pad(padId, padDb);
|
||||
await pad.init(null, authorId);
|
||||
await pad.check();
|
||||
} finally {
|
||||
await padDb.close();
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
...[...dbRecords].map(([k, v]) => q.pushAsync(() => db.set(k, v))),
|
||||
...[...data].map(([k, v]) => q.pushAsync(() => db.set(k, v))),
|
||||
...[...existingAuthors].map((a) => q.pushAsync(() => authorManager.addPad(a, padId))),
|
||||
]);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue