deyles-zz / sculejs

SculeJS - data structures for the web
165 stars 24 forks source link

Commiting a 2nd time does not seem to work with adapter for titanium #57

Closed davidcyp closed 8 years ago

davidcyp commented 8 years ago

Commit does not seem to flush to the storage on the mobile device.

Initially, the code contained commit() statements after every operation. We have noticed that the collection contained all elements as long as the application was not closed. After a restart, the application only contained one entry(the very first commit).

Thus we set autoCommit to true for all our collections, and we print out our collection when the app starts, then we add some entries, and then we fetch the collection again and print it out. As you can see in the logs, only 3 items get printed, while we expected that our collection would grow each time.

See Archief.zip for our persisted and temporary collections from our app. You can see that the new records are available in the .json.tmp file, but not in the .json file (note: these files are from code with autocommit not set to true, but with a commit after each operation on the collection).

You can find a simplified example below:

var scule = require('com.scule.min');
var collection = scule.factoryCollection('scule+titanium://test2');
collection.setAutoCommit(true);

collection.findAll(function(documents) {
    console.error('DUMPING collection');
    documents.forEach(function(document) {
        console.error('collection entry: ' + JSON.stringify(document));
    });
});

collection.save({foo:'bar'});
collection.save({foo:'fighter'});
//collection.commit();

collection.save({bar:'bar'});
//collection.commit();

collection.findAll(function(documents) {
    console.error('AFTER collection');
    documents.forEach(function(document) {
        console.error('collection entry: ' + JSON.stringify(document));
    });
});

function doClick(e) {
    alert($.label.text);
}

$.index.open();
[INFO] :   Application started
[INFO] :   SandboxDavidMultiWIndowScule/1.0 (5.2.0.384775e)
[ERROR] :  DUMPING collection
[ERROR] :  collection entry: {"foo":"bar","_id":{"id":"56e0320eed277826ac05494f","$type":"id"}}
[ERROR] :  collection entry: {"foo":"fighter","_id":{"id":"56e0320eed27780ac6075d2d","$type":"id"}}
[ERROR] :  collection entry: {"bar":"bar","_id":{"id":"56e0320eed277817710cef86","$type":"id"}}
[ERROR] :  AFTER collection
[ERROR] :  collection entry: {"foo":"bar","_id":{"id":"56e0320eed277826ac05494f","$type":"id"}}
[ERROR] :  collection entry: {"foo":"fighter","_id":{"id":"56e0320eed27780ac6075d2d","$type":"id"}}
[ERROR] :  collection entry: {"bar":"bar","_id":{"id":"56e0320eed277817710cef86","$type":"id"}}
[ERROR] :  collection entry: {"foo":"bar","_id":{"id":"56e032216b1c2c1cb30b23d4","$type":"id"}}
[ERROR] :  collection entry: {"foo":"fighter","_id":{"id":"56e032216b1c2c1cef09d88d","$type":"id"}}
[ERROR] :  collection entry: {"bar":"bar","_id":{"id":"56e032216b1c2c18be0ceaa8","$type":"id"}}
[INFO] :   Application started
[INFO] :   SandboxDavidMultiWIndowScule/1.0 (5.2.0.384775e)
[ERROR] :  DUMPING collection
[ERROR] :  collection entry: {"foo":"bar","_id":{"id":"56e0320eed277826ac05494f","$type":"id"}}
[ERROR] :  collection entry: {"foo":"fighter","_id":{"id":"56e0320eed27780ac6075d2d","$type":"id"}}
[ERROR] :  collection entry: {"bar":"bar","_id":{"id":"56e0320eed277817710cef86","$type":"id"}}
[ERROR] :  AFTER collection
[ERROR] :  collection entry: {"foo":"bar","_id":{"id":"56e0320eed277826ac05494f","$type":"id"}}
[ERROR] :  collection entry: {"foo":"fighter","_id":{"id":"56e0320eed27780ac6075d2d","$type":"id"}}
[ERROR] :  collection entry: {"bar":"bar","_id":{"id":"56e0320eed277817710cef86","$type":"id"}}
[ERROR] :  collection entry: {"foo":"bar","_id":{"id":"56e0322e9bfeca24e706dc40","$type":"id"}}
[ERROR] :  collection entry: {"foo":"fighter","_id":{"id":"56e0322e9bfeca112d05ff5b","$type":"id"}}
[ERROR] :  collection entry: {"bar":"bar","_id":{"id":"56e0322e9bfeca0f910f07da","$type":"id"}}
davidcyp commented 8 years ago

UPDATE: I have added a commit() after save() (the documentation for autocommit tells us: "Tells the collection whether or not to auto-commit after each update, the semaphor value is a boolean". Though the error remains.

davidcyp commented 8 years ago

UPDATE 2: I have set autocommit to false, and provided a callback method for each commit. As you can see, both commits are executed, but this is not reflected in the collection (on application restart)

Launching iOS Simulator
[ERROR] :  DUMPING collection
[ERROR] :  collection entry: {"foo":"bar","_id":{"id":"56e0320eed277826ac05494f","$type":"id"}}
[ERROR] :  collection entry: {"foo":"fighter","_id":{"id":"56e0320eed27780ac6075d2d","$type":"id"}}
[ERROR] :  collection entry: {"bar":"bar","_id":{"id":"56e0320eed277817710cef86","$type":"id"}}
[ERROR] :  Commit for Star Trek and Cpt America
[ERROR] :  Commit for Nick Cave
[ERROR] :  AFTER collection
[ERROR] :  collection entry: {"foo":"bar","_id":{"id":"56e0320eed277826ac05494f","$type":"id"}}
[ERROR] :  collection entry: {"foo":"fighter","_id":{"id":"56e0320eed27780ac6075d2d","$type":"id"}}
[ERROR] :  collection entry: {"bar":"bar","_id":{"id":"56e0320eed277817710cef86","$type":"id"}}
[ERROR] :  collection entry: {"star":"trek","_id":{"id":"56e038b84500da0e46091596","$type":"id"}}
[ERROR] :  collection entry: {"captain":"america","_id":{"id":"56e038b84500da15380904c3","$type":"id"}}
[ERROR] :  collection entry: {"nick":"cave","_id":{"id":"56e038b84500da238408bd03","$type":"id"}}
[INFO] :   Application started
[INFO] :   SandboxDavidMultiWIndowScule/1.0 (5.1.2.ca822b2)
[ERROR] :  DUMPING collection
[ERROR] :  collection entry: {"foo":"bar","_id":{"id":"56e0320eed277826ac05494f","$type":"id"}}
[ERROR] :  collection entry: {"foo":"fighter","_id":{"id":"56e0320eed27780ac6075d2d","$type":"id"}}
[ERROR] :  collection entry: {"bar":"bar","_id":{"id":"56e0320eed277817710cef86","$type":"id"}}
[ERROR] :  Commit for Star Trek and Cpt America
[ERROR] :  Commit for Nick Cave
[ERROR] :  AFTER collection
[ERROR] :  collection entry: {"foo":"bar","_id":{"id":"56e0320eed277826ac05494f","$type":"id"}}
[ERROR] :  collection entry: {"foo":"fighter","_id":{"id":"56e0320eed27780ac6075d2d","$type":"id"}}
[ERROR] :  collection entry: {"bar":"bar","_id":{"id":"56e0320eed277817710cef86","$type":"id"}}
[ERROR] :  collection entry: {"star":"trek","_id":{"id":"56e038cb0109f5214403d4ef","$type":"id"}}
[ERROR] :  collection entry: {"captain":"america","_id":{"id":"56e038cb0109f525ba073d58","$type":"id"}}
[ERROR] :  collection entry: {"nick":"cave","_id":{"id":"56e038cb0109f50da902fab5","$type":"id"}}

The code:

var scule = require('com.scule.min');
var collection = scule.factoryCollection('scule+titanium://test2');
/*
collection.setAutoCommit(true, function(){
    console.error('#### autocommit triggered!!!! ');
//  alert('Hi ho');
});
*/

collection.findAll(function(documents) {
    console.error('DUMPING collection');
    documents.forEach(function(document) {
        console.error('collection entry: ' + JSON.stringify(document));
    });
});

collection.save({star:'trek'});
collection.save({captain:'america'});
//collection.commit();
collection.commit(function(){
    console.error('Commit for Star Trek and Cpt America');
});

// collection = scule.factoryCollection('scule+titanium://test2');
collection.save({nick:'cave'});
collection.commit(function(){
    console.error('Commit for Nick Cave');
});

collection.findAll(function(documents) {
    console.error('AFTER collection');
    documents.forEach(function(document) {
        console.error('collection entry: ' + JSON.stringify(document));
    });
});
davidcyp commented 8 years ago

I have added some debugging to scule.js, neither 'rename' or 'move' seem to work (if the file already exists). So I guess it might be a Titanium or OS related issue?

   * Writes data to storage
         * @public
         * @param {String} name the name of the file to write data to
         * @param {Object} object the data to write
         * @param {Function} callback the callback to execute once writing to storage is complete
         * @returns {Void}
         */ 
        this.write = function(name, object, callback) {
            if(!object._salt) {
                object._salt = Scule.sha1.hash((new Date()).getTime() + '');
            }
            object._sig = this.crypto.signObject(object, this.configuration.secret, object._salt);
            var realPath = name + '.json';
            var tmpPath = realPath + '.tmp';
            var file = Titanium.Filesystem.getFile(this.configuration.path, tmpPath);
            file.write(JSON.stringify(object));

            // var isRenamed = file.rename(realPath);
            var isRenamed = file.move(realPath);
            console.error('### RENAME SUCCEEDED = ' + isRenamed);
            if(callback) {
                callback(object);
            }
            return true;
        };

See log: It goes wrong from the moment the destination file exists.

[ERROR] :  DUMPING collection
[ERROR] :  #### SCULE ### documents = (h) {"_id":{"id":"STARTREK","$type":"id"},"star":"trek"} -> {"_id":{"id":"CAPITAN","$type":"id"},"captain":"america"} -> (t)
[ERROR] :  ### SCULE RENAME = true
[ERROR] :  Commit for Star Trek and Cpt America
[ERROR] :  #### SCULE ### documents = (h) {"_id":{"id":"STARTREK","$type":"id"},"star":"trek"} -> {"_id":{"id":"CAPITAN","$type":"id"},"captain":"america"} -> {"_id":{"id":"NICKCAVE","$type":"id"},"nick":"cave"} -> (t)
[ERROR] :  ### SCULE RENAME = false
[ERROR] :  Commit for Nick Cave
[ERROR] :  AFTER collection
[ERROR] :  in memory entry: {"_id":{"id":"STARTREK","$type":"id"},"star":"trek"}
[ERROR] :  in memory entry: {"_id":{"id":"CAPITAN","$type":"id"},"captain":"america"}
[ERROR] :  in memory entry: {"_id":{"id":"NICKCAVE","$type":"id"},"nick":"cave"}
[INFO] :   SandboxDavidMultiWIndowScule/1.0 (5.2.0.384775e)
[ERROR] :  DUMPING collection
[ERROR] :  collection entry: {"_id":{"id":"STARTREK","$type":"id"},"star":"trek"}
[ERROR] :  collection entry: {"_id":{"id":"CAPITAN","$type":"id"},"captain":"america"}
[ERROR] :  #### SCULE ### documents = (h) {"_id":{"id":"STARTREK","$type":"id"},"star":"trek"} -> {"_id":{"id":"CAPITAN","$type":"id"},"captain":"america"} -> (t)
[ERROR] :  ### SCULE RENAME = false
[ERROR] :  Commit for Star Trek and Cpt America
[ERROR] :  #### SCULE ### documents = (h) {"_id":{"id":"STARTREK","$type":"id"},"star":"trek"} -> {"_id":{"id":"CAPITAN","$type":"id"},"captain":"america"} -> {"_id":{"id":"NICKCAVE","$type":"id"},"nick":"cave"} -> (t)
[ERROR] :  ### SCULE RENAME = false
[ERROR] :  Commit for Nick Cave
[ERROR] :  AFTER collection
[ERROR] :  in memory entry: {"_id":{"id":"STARTREK","$type":"id"},"star":"trek"}
[ERROR] :  in memory entry: {"_id":{"id":"CAPITAN","$type":"id"},"captain":"america"}
[ERROR] :  in memory entry: {"_id":{"id":"NICKCAVE","$type":"id"},"nick":"cave"}
davidcyp commented 8 years ago

Found a solution! (see my work-in-progress below). It seems that existing files cannot be deleted. Not sure if it is due to locking, os-changes or titanium changes.

        this.write = function(name, object, callback) {
            if(!object._salt) {
                object._salt = Scule.sha1.hash((new Date()).getTime() + '');
            }
            object._sig = this.crypto.signObject(object, this.configuration.secret, object._salt);
            var realPath = name + '.json';
            var tmpPath = realPath + '.tmp';
            var file = Titanium.Filesystem.getFile(this.configuration.path, tmpPath);
            file.write(JSON.stringify(object));

            var destFile = Titanium.Filesystem.getFile(this.configuration.path, realPath);
            if(destFile.exists()){
                var isDeleted = destFile.deleteFile();
                console.error("### SCULE destFile deleted  =" + isDeleted);
            }

            // var isRenamed = file.rename(realPath);
            var isRenamed = file.move(realPath);
            console.error('### SCULE RENAME = ' + isRenamed);
            if(callback) {
                callback(object);
            }
            return true;
        };

@dan-eyles should I make a pull request of this code (after cleanup)? Because it might be OS or Titanium related

davidcyp commented 8 years ago

Merged