diff --git a/exec/load/json-db.js b/exec/load/json-db.js
index dc887ea47dee1806c970ccb809bcf458a0aba7f2..23008c089a6e960a0d96c0f597220c760cbf417f 100644
--- a/exec/load/json-db.js
+++ b/exec/load/json-db.js
@@ -74,6 +74,22 @@ function JSONdb (fileName) {
 		WRITE:2,
 	}
 	
+	/* operation constants */
+	var opers = {
+		READ:0,
+		WRITE:1,
+		LOCK:2,
+		PUSH:3,
+		POP:4,
+		SHIFT:5,
+		UNSHIFT:6,
+		DELETE:7,
+		SUBSCRIBE:8,
+		UNSUBSCRIBE:9,
+		WHO:10,
+		STATUS:11
+	}
+	
 	/* error constants */
 	var errors = {
 		INVALID_REQUEST:0,
@@ -84,7 +100,9 @@ function JSONdb (fileName) {
 		DUPLICATE_LOCK:5,
 		DUPLICATE_SUB:6,
 		NON_ARRAY:7,
-		READ_ONLY:8
+		READ_ONLY:8,
+		INVALID_LOCK:9,
+		INVALID_OPER:10
 	};
 	
 	/*************************** database methods ****************************/
@@ -409,6 +427,15 @@ function JSONdb (fileName) {
 
 		/* if an operation is requested */
 		if(query.oper !== undefined) {
+			if(!valid_oper(query.oper)) {
+				this.error(client,errors.INVALID_OPER);
+				return false;
+			}
+			if(query.oper == "LOCK" && !valid_lock(query.data)) {
+				this.error(client,errors.INVALID_LOCK);
+				return false;
+			}
+
 			request = new Request(client,query.oper,parent_name,child_name,query.data);
 			/* push this query into a queue to be processed at the next response cycle (this.cycle()) */;
 			q.push(request);
@@ -416,6 +443,10 @@ function JSONdb (fileName) {
 		
 		/* if there is an attached lock operation, process accordingly */
 		if(query.lock !== undefined) {	
+			if(!valid_lock(query.lock)) {
+				this.error(client,errors.INVALID_LOCK);
+				return false;
+			}
 			/* put lock ahead of the operation in request queue */
 			q.unshift(new Request(
 				client,"LOCK",parent_name,child_name,query.lock
@@ -458,9 +489,15 @@ function JSONdb (fileName) {
 		case errors.NON_ARRAY:
 			error_desc="Record is not an array";
 			break;
-		case this.settings.READ_ONLY:
+		case errors.READ_ONLY:
 			error_desc="Record is read-only";
 			break;
+		case errors.INVALID_LOCK:
+			error_desc="Unknown lock type";
+			break;
+		case errors.INVALID_OPER:
+			error_desc="Unknown operation";
+			break;
 		}
 		var error=new Error(error_num,error_desc);
 		send_packet(client,error,"ERROR");
@@ -521,18 +558,26 @@ function JSONdb (fileName) {
         this.settings.LAST_SAVE = Date.now();
 		log(LOG_INFO,"database initialized (v" + this.VERSION + ")");
 	};
-    
-	/* release any locks or subscriptions held by a disconnected client */
+ 
+	/* schedule client for subscription and lock release */
 	this.release = function(client) {
+		this.queue.push(new Request(
+			client,"CLOSE"
+		));
+	}
+ 
+	/* release any locks or subscriptions held by a disconnected client */
+	this.close = function(client) {
+		/* release any locks the client holds */
 		free_prisoners(client,this.shadow);
-		for (var s in this.subscriptions[client.id]) {
-			cancel_subscriptions(client,this.subscriptions[client.id]);
-			delete this.subscriptions[client.id];
-		}
-		for(var c=0;c<this.queue.length;c++) {
-			if(this.queue[c].client.id == client.id)
-				this.queue.splice(c--,1);
-		}
+		
+		/* release any subscriptions the client holds */
+		cancel_subscriptions(client,this.subscriptions[client.id]);
+		
+		/* remove any remaining queries from the queue */
+		fuh_queue(client,this.queue);
+		
+		return true;
 	};
 	
     /* main "loop" called by server */
@@ -541,6 +586,14 @@ function JSONdb (fileName) {
 		for(var r=0;r<this.queue.length;r++) {
 			var request=this.queue[r];
 			var result=false;
+			
+			/* if we have been asked to clear a client's locks, DEW IT */
+			if(request.oper.toUpperCase() == "CLOSE") {
+				this.queue.splice(r--,1);
+				this.close(request.client);
+				continue;
+			}	
+			
 			/* locate the requested record within the database */
 			var record=identify_remains.call(
 				this,request.client,request.parent_name,request.child_name,
@@ -592,19 +645,13 @@ function JSONdb (fileName) {
 				break;
 			}
 			if(result == true) {
-				log(LOG_DEBUG,"db: " + 
-					request.client.id + " " + 
-					request.oper + " " + 
-					record.location + " OK"
-				);
+				log(LOG_DEBUG,format("db: %s %s %s OK",
+					request.client.id,request.oper,record.location));  
 				this.queue.splice(r--,1);
 			}
 			else {
-				log(LOG_DEBUG,"db: " + 
-					request.client.id + " " + 
-					request.oper + " " + 
-					record.location + " FAILED"
-				); 
+				log(LOG_DEBUG,format("db: %s %s %s FAILED",
+					request.client.id,request.oper,record.location));  
 			}
 		} 
 		if(!this.settings.UPDATES)
@@ -756,6 +803,18 @@ function JSONdb (fileName) {
 		}
 	}
 	
+	/* remove any remaining client queries from queue */
+	function fuh_queue(client,queue) {
+		for(var c=0;c<queue.length;c++) {
+			var query = queue[c];
+			if(query.client.id == client.id) {
+				log(LOG_DEBUG,format("removing query: %s %s.%s",
+					query.oper,query.parent_name,query.child_name));
+				queue.splice(c--,1);
+			}
+		}
+	}
+	
 	/* release subscriptions on an object recursively */
 	function cancel_subscriptions(client,records) {
 		for(var r in records) {
@@ -764,6 +823,7 @@ function JSONdb (fileName) {
 			delete record.shadow[record.child_name]._subscribers[client.id];
 			send_subscriber_updates(client,record,"UNSUBSCRIBE");
 		}
+		delete records;
 	}
 	
 	/* return the prevailing lock type and pending lock status for an object */
@@ -857,6 +917,22 @@ function JSONdb (fileName) {
 		return undefined;
 	}
 	
+	/* check a lock value against valid lock types */
+	function valid_lock(lock) {
+		for each(var l in locks) {
+			if(l == lock) 
+				return true;
+		}
+		return false;
+	}
+	
+	/* check an operation against valid operation types */
+	function valid_oper(oper) {
+		if(opers[oper] !== undefined)
+			return true;
+		return false;
+	}
+	
 	/* parse child object name from a dot-delimited string */
 	function get_cname(str) {
 		var i = str.lastIndexOf('.');