petersirka/nosql

Remove failing to delete / reporting wrong number of records removed

tregenza opened this issue · 4 comments

I have a simple piece of code to create db entries from hard coded account data. It first tries to delete any existing records for the account and then create it. On an empty database this works correctly. but running it a second or subsequent time gives the wrong results:

  1. no records are actually delete from the file
  2. the 'count' supplied by the remove function is inconsistent.

---- Example Output [MY NOTATION IN BRACKETS] ----

[CHECK DB IS EMPTY]

admin@rabbit:/var/www/nodes/twittermanager$ cat ./nosql/accounts.nosql
cat: ./nosql/accounts.nosql: No such file or directory

[RUN CODE FOR FIRST TIME. REMOVED DOCUMENTS COUNT IS CORRECTLY REPORTED AS ZERO]

admin@rabbit:/var/www/nodes/twittermanager$ node setupaccounts.js

processAccount recordy
Delete recordy

processAccount recordx
Delete recordx
myCallback

removed documents: recordy 0
Create recordy
removed documents: recordx 0
Create recordx
inserted: recordy
completedCallback { delete: 'No Error on Removal',
create: 'No Error on Insertion' }
inserted: recordx
completedCallback { delete: 'No Error on Removal',
create: 'No Error on Insertion' }

[CHECK CONTENTS OF DB. IT CONTAINS TWO RECORDS AS EXPECTED]

admin@rabbit:/var/www/nodes/twittermanager$ cat ./nosql/accounts.nosql
{"screen_name":"recordy","consumer_key":"y","consumer_secret":"y","access_token_key":"y","access_token_secret":"y"}
{"screen_name":"recordx","consumer_key":"x","consumer_secret":"x","access_token_key":"x","access_token_secret":"x"}

[RUN CODE AGAIN. NOTE HOW THE REMOVE FOR recordy = 1 BUT recordX = 0. BOTH SHOULD BE ONE.]

admin@rabbit:/var/www/nodes/twittermanager$ node setupaccounts.js

processAccount recordy
Delete recordy

processAccount recordx
Delete recordx
myCallback

removed documents: recordy 1
Create recordy
removed documents: recordx 0
Create recordx
inserted: recordy
completedCallback { delete: 'No Error on Removal',
create: 'No Error on Insertion' }
inserted: recordx
completedCallback { delete: 'No Error on Removal',
create: 'No Error on Insertion' }

[NOW DUMP THE DATABASE AGAIN. NOTE THAT NEITHER THE ORIGINAL RECORDS FOR recordx OR recordy HAVE BEEN DELETED DESPITE WHAT THE COUNT REPORTED.]

admin@rabbit:/var/www/nodes/twittermanager$ cat ./nosql/accounts.nosql
{"screen_name":"recordy","consumer_key":"y","consumer_secret":"y","access_token_key":"y","access_token_secret":"y"}
{"screen_name":"recordx","consumer_key":"x","consumer_secret":"x","access_token_key":"x","access_token_secret":"x"}
{"screen_name":"recordy","consumer_key":"y","consumer_secret":"y","access_token_key":"y","access_token_secret":"y"}
{"screen_name":"recordx","consumer_key":"x","consumer_secret":"x","access_token_key":"x","access_token_secret":"x"}

---- Code for setupaccounts.js ----


/*  	Creates / Updates database with account details */
'use strict';
var NoSQL = require('nosql');
var db = NoSQL.load('./nosql/accounts.nosql');
var async = require('async');
/* Setup basic string data */
var accountData = [
	{
	  screen_name: "recordy",
	  consumer_key: "y",
	  consumer_secret: "y",
	  access_token_key: "y",
	  access_token_secret: "y"
	},
	{
	  screen_name: "tregenza",
	  consumer_key: "x",
	  consumer_secret: "x",
	  access_token_key: "x",
	  access_token_secret: "x"
	}
	];

/* Create object to wrap round functions and share data */
var Account = function(accountRecord) {
	this.accountRecord = accountRecord;
	this.deleteAccount = function (callback) {
		console.log("Delete",accountRecord.screen_name);

		db.remove().make(function(builder) {
	    	    builder.where('screen_name', '=', accountRecord.screen_name); 
		    builder.callback(function(err, count) {
				if ( err ) {
					console.log('error removing: ', accountRecord.screen_name);
					console.log(err);
					callback("Error");
				} else {
		        	console.log('removed documents:', accountRecord.screen_name, count);
					callback(null,"No Error on Removal");
				}
		    });
		});
	};

	this.createAccount = function (callback) {
		console.log("Create",accountRecord.screen_name);

		db.insert(accountRecord).callback( function(err, count) {
			if ( err ) {
				console.log('error inserting: ', accountRecord.screen_name);
				console.log(err);
				callback("Insert Error");
			} else {
    	        	        console.log('inserted:', accountRecord.screen_name);
				callback(null,"No Error on Insertion");
			}		
		});
	};
	
	this.completedCallback = function (err, data) {
		if ( err ) {
			console.log("completedCallback", err);
		} else 	if ( data ) {
			console.log("completedCallback", data);
		} else {
			console.log("completedCallback");
		}
		return "completedCallback";
	};

	this.dbErrorCallback = function ( err ) {
		console.log("dbErrorCallback");
	};
};

async.each(accountData, processAccount, myCallback);

function myCallback(err, data) {
	if ( err ) {
		console.log("myCallback", err,"\n");
	} else 	if ( data ) {
		console.log("myCallback", data,"\n");
	} else {
		console.log("myCallback","\n");
	}
	return "callback";
}

function processAccount(accountRecord, callback) {
	console.log("\nprocessAccount", accountRecord.screen_name);
	var account = new Account(accountRecord);
	async.series({
		delete: account.deleteAccount,
		create: account.createAccount
		}, 
		account.completedCallback
	);	 /* async series */

	callback(null, accountRecord.screen_name);

}

I've tried reducing this to a simpler example but they all behave as expected so suspect it is some aspect of the timing of the various operations.

Chris

Hi @tregenza, I'll look on it ASAP.

I found a problem.
Please download https://github.com/totaljs/framework/blob/v2.3.0/nosql.js and you have to replace /node_modules/nosql/node_modules/total.js/nosql.js file.

I can't publish fix into the NPM yet, but I'll publish it this month.
100x thanks!!!

@tregenza you can use latest beta version npm install nosql@beta. Thank you!

Sorry for the delay, just circled back to this.

Installed the beta version as suggested and it works as expect now.

Thanks for the fix.