Skip to content
Snippets Groups Projects
Select Git revision
  • 8bf2368892d5148da2e072b8fe55b91c1b1a755b
  • master default protected
  • greenkeeper/webpack-4.10.1
  • greenkeeper/webpack-4.10.0
  • greenkeeper/webpack-4.9.2
  • greenkeeper/promise-polyfill-8.0.0
  • greenkeeper/webpack-4.9.1
  • greenkeeper/webpack-4.9.0
  • greenkeeper/webpack-manifest-plugin-2.0.3
  • greenkeeper/update-to-node-10
  • gh-pages
  • greenkeeper/webpack-4.8.3
  • greenkeeper/webpack-4.8.2
  • greenkeeper/webpack-4.7.0
  • greenkeeper/webpack-manifest-plugin-2.0.2
  • greenkeeper/webpack-manifest-plugin-2.0.1
  • greenkeeper/style-loader-0.21.0
  • greenkeeper/webpack-4.6.0
  • greenkeeper/sass-loader-7.0.1
  • greenkeeper/sass-loader-7.0.0
  • greenkeeper/webpack-manifest-plugin-2.0.0
  • 2.7.3
  • 2.7.2
  • 2.7.1
  • 2.7.0
  • 2.6.6
  • 2.6.5
  • 2.6.4
  • 2.6.3
  • 2.6.2
  • 2.6.1
  • 2.6.0
  • 2.5.5
  • 2.5.4
  • 2.5.3
  • 2.5.2
  • 2.5.1
  • 2.5.0
  • 2.4.0
  • 2.3.0
  • 2.2.6
41 results

setup.py

Blame
  • sync-simple.js 1.99 KiB
    let { existsSync, readFileSync } = require('fs');
    let { join } = require('path');
    let { openDatabase } = require('./db');
    
    let actual = require('@actual-app/api');
    let merkle = actual.internal.merkle;
    let Timestamp = actual.internal.timestamp.Timestamp;
    
    function getGroupDb(groupId) {
      let path = join(__dirname, `user-files/${groupId}.sqlite`);
      let needsInit = !existsSync(path);
    
      let db = openDatabase(path);
    
      if (needsInit) {
        let sql = readFileSync(join(__dirname, 'sql/messages.sql'), 'utf8');
        db.exec(sql);
      }
    
      return db;
    }
    
    function addMessages(db, messages) {
      let returnValue;
      db.transaction(() => {
        let trie = getMerkle(db);
    
        if (messages.length > 0) {
          for (let msg of messages) {
            let info = db.mutate(
              `INSERT OR IGNORE INTO messages_binary (timestamp, is_encrypted, content)
                 VALUES (?, ?, ?)`,
              [
                msg.getTimestamp(),
                msg.getIsencrypted() ? 1 : 0,
                Buffer.from(msg.getContent())
              ]
            );
    
            if (info.changes > 0) {
              trie = merkle.insert(trie, Timestamp.parse(msg.getTimestamp()));
            }
          }
        }
    
        trie = merkle.prune(trie);
    
        db.mutate(
          'INSERT INTO messages_merkles (id, merkle) VALUES (1, ?) ON CONFLICT (id) DO UPDATE SET merkle = ?',
          [JSON.stringify(trie), JSON.stringify(trie)]
        );
    
        returnValue = trie;
      });
    
      return returnValue;
    }
    
    function getMerkle(db, group_id) {
      let rows = db.all('SELECT * FROM messages_merkles', [group_id]);
    
      if (rows.length > 0) {
        return JSON.parse(rows[0].merkle);
      } else {
        // No merkle trie exists yet (first sync of the app), so create a
        // default one.
        return {};
      }
    }
    
    function sync(messages, since, fileId) {
      let db = getGroupDb(fileId);
      let newMessages = db.all(
        `SELECT * FROM messages_binary
             WHERE timestamp > ?
             ORDER BY timestamp`,
        [since],
        true
      );
    
      let trie = addMessages(db, messages);
    
      return { trie, newMessages };
    }
    
    module.exports = { sync };