diff --git a/backend/lib/GitSheets.js b/backend/lib/GitSheets.js index c9c42ae..3a6adf3 100644 --- a/backend/lib/GitSheets.js +++ b/backend/lib/GitSheets.js @@ -265,6 +265,41 @@ module.exports = class GitSheets { await this.git.branch({D: true}, dstRef); // force delete in case srcRef is not checked out } + async createTransaction (parentRef) { + const pathTemplate = await this.getConfigItem(parentRef, 'path'); + const treeObject = await this._createTreeFromRef(parentRef); + const gitSheets = this; + + // TODO: Use a class or something, rather than generating this code each transaction + return { + upsert: function upsert (data) { + const path = gitSheets._renderTemplate(pathTemplate, data); + const contents = gitSheets._serialize(data); + // TODO: Wrap errors + return treeObject.writeChild(`${path}.toml`, contents); + }, + async save (saveToBranch = parentRef) { + // TODO: Wrap errors + const treeHash = await treeObject.write(); + + if (saveToBranch && saveToBranch === parentRef) { // TODO: check if branch exists instead + await gitSheets._saveTreeToExistingBranch({ + treeHash, + branch: saveToBranch, + msg: 'import to existing branch', + }); + } else if (saveToBranch) { + await gitSheets._saveTreeToNewBranch({ + treeHash, + parentRef, + branch: saveToBranch, + msg: 'import to new branch', + }); + } + }, + }; + } + _isDataBlob ([key, blob]) { return !key.startsWith('.gitsheets/') && key.endsWith('.toml') && blob instanceof BlobObject; } diff --git a/backend/test/GitSheets.spec.js b/backend/test/GitSheets.spec.js index 0817cde..12ec662 100644 --- a/backend/test/GitSheets.spec.js +++ b/backend/test/GitSheets.spec.js @@ -357,6 +357,34 @@ describe('GitSheets lib', () => { .toThrow(MergeError); }); }); + + describe.only('Transaction', () => { + it('upserts on top of branch', async () => { + await gitSheets.setConfigItem('master', 'path', '{{id}}'); + + const txn = await gitSheets.createTransaction('master'); + await txn.upsert(sampleData.initial[0]); + await txn.upsert(sampleData.initial[1]); + await txn.save(); + + const response = await gitSheets.git.lsTree('master'); + const tree = parseTree(response); + + const blobs = tree.filter((item) => item.type === 'blob'); + expect(blobs.length).toBe(2); + + await Promise.all(blobs.map(verifyBlob)); + + async function verifyBlob ({ hash, file }) { + const sampleDataItem = sampleData.initial.find((item) => item.id === file.substr(0, file.length - 5)); + expect(sampleDataItem).toBeDefined(); + + const contents = await gitSheets.git.catFile('blob', hash); + const data = gitSheets._deserialize(contents); + expect(data).toEqual(sampleDataItem); + } + }) + }) }); function parseTree (treeOutput) {