123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- "use strict";
- var codec = require('../lib/object-codec.js');
- var bodec = require('bodec');
- var inflate = require('../lib/inflate');
- var deflate = require('../lib/deflate');
- var sha1 = require('git-sha1');
- var modes = require('../lib/modes.js');
- var db;
- mixin.init = init;
- mixin.loadAs = loadAs;
- mixin.saveAs = saveAs;
- mixin.loadRaw = loadRaw;
- mixin.saveRaw = saveRaw;
- module.exports = mixin;
- function mixin(repo, prefix) {
- if (!prefix) throw new Error("Prefix required");
- repo.refPrefix = prefix;
- repo.saveAs = saveAs;
- repo.saveRaw = saveRaw;
- repo.loadAs = loadAs;
- repo.loadRaw = loadRaw;
- repo.readRef = readRef;
- repo.updateRef = updateRef;
- repo.hasHash = hasHash;
- }
- function init(callback) {
- db = openDatabase('tedit', '1.0', 'tedit local data', 10 * 1024 * 1024);
- db.transaction(function (tx) {
- tx.executeSql(
- 'CREATE TABLE IF NOT EXISTS objects (hash unique, body blob)'
- );
- tx.executeSql(
- 'CREATE TABLE IF NOT EXISTS refs (path unique, value text)'
- );
- }, function () {
- console.error(arguments);
- callback(new Error("Problem initializing database"));
- }, function () {
- callback();
- });
- }
- function saveAs(type, body, callback) {
- /*jshint: validthis: true */
- if (!callback) return saveAs.bind(this, type, body);
- var hash, buffer;
- try {
- buffer = codec.frame({type:type,body:body});
- hash = sha1(buffer);
- }
- catch (err) { return callback(err); }
- this.saveRaw(hash, buffer, callback);
- }
- function saveRaw(hash, buffer, callback) {
- /*jshint: validthis: true */
- if (!callback) return saveRaw.bind(this, hash, buffer);
- var sql = 'INSERT INTO objects (hash, body) VALUES (?, ?)';
- db.transaction(function (tx) {
- var text;
- try {
- text = bodec.toBase64(deflate(buffer));
- }
- catch (err) {
- return callback(err);
- }
- tx.executeSql(sql, [hash, text], function () {
- callback(null, hash);
- });
- });
- }
- function loadAs(type, hash, callback) {
- /*jshint: validthis: true */
- if (!callback) return loadAs.bind(this, type, hash);
- loadRaw(hash, function (err, buffer) {
- if (!buffer) return callback(err);
- var parts, body;
- try {
- parts = codec.deframe(buffer);
- if (parts.type !== type) throw new Error("Type mismatch");
- body = codec.decoders[type](parts.body);
- }
- catch (err) {
- return callback(err);
- }
- callback(null, body);
- });
- }
- function loadRaw(hash, callback) {
- /*jshint: validthis: true */
- if (!callback) return loadRaw.bind(this, hash);
- var sql = 'SELECT * FROM objects WHERE hash=?';
- db.readTransaction(function (tx) {
- tx.executeSql(sql, [hash], function (tx, result) {
- if (!result.rows.length) return callback();
- var item = result.rows.item(0);
- var buffer;
- try {
- buffer = inflate(bodec.fromBase64(item.body));
- }
- catch (err) {
- return callback(err);
- }
- callback(null, buffer);
- }, function (tx, error) {
- callback(new Error(error.message));
- });
- });
- }
- function hasHash(type, hash, callback) {
- /*jshint: validthis: true */
- loadAs(type, hash, function (err, value) {
- if (err) return callback(err);
- if (value === undefined) return callback(null, false);
- if (type !== "tree") return callback(null, true);
- var names = Object.keys(value);
- next();
- function next() {
- if (!names.length) return callback(null, true);
- var name = names.pop();
- var entry = value[name];
- hasHash(modes.toType(entry.mode), entry.hash, function (err, has) {
- if (err) return callback(err);
- if (has) return next();
- callback(null, false);
- });
- }
- });
- }
- function readRef(ref, callback) {
- /*jshint: validthis: true */
- var key = this.refPrefix + "/" + ref;
- var sql = 'SELECT * FROM refs WHERE path=?';
- db.transaction(function (tx) {
- tx.executeSql(sql, [key], function (tx, result) {
- if (!result.rows.length) return callback();
- var item = result.rows.item(0);
- callback(null, item.value);
- }, function (tx, error) {
- callback(new Error(error.message));
- });
- });
- }
- function updateRef(ref, hash, callback) {
- /*jshint: validthis: true */
- var key = this.refPrefix + "/" + ref;
- var sql = 'INSERT INTO refs (path, value) VALUES (?, ?)';
- db.transaction(function (tx) {
- tx.executeSql(sql, [key, hash], function () {
- callback();
- }, function (tx, error) {
- callback(new Error(error.message));
- });
- });
- }
|