Skip to content
Browse files

+ fix blob writes

+ allow insert of dates from string or number
+ params are optionals
+ increment version number
  • Loading branch information...
1 parent d34a4f9 commit 9a990262dc5257601dd6cc3a016313cef774eb56 @hgourvest committed Nov 12, 2012
Showing with 207 additions and 95 deletions.
  1. +194 −86 lib/index.js
  2. +12 −8 lib/serialize.js
  3. +1 −1 package.json
View
280 lib/index.js
@@ -800,8 +800,8 @@ function SQLParamQuad(value) {
SQLParamQuad.prototype.encode = function(data) {
if (this.value != null) {
- data.addInt(this.value.low);
data.addInt(this.value.high);
+ data.addInt(this.value.low);
data.addInt(0);
} else {
data.addInt(0);
@@ -948,7 +948,7 @@ Transaction.prototype.newStatement = function(query, callback) {
Transaction.prototype.execute = function(query, params, callback) {
if (params instanceof Function) {
callback = params;
- params = null;
+ params = undefined;
}
var self = this;
@@ -1394,8 +1394,8 @@ Connection.prototype.connect = function (database, callback) {
msg.addInt(PROTOCOL_VERSION10);
msg.addInt(ARCHITECTURE_GENERIC);
- msg.addInt(ptype_batch_send); // Min type
- msg.addInt(ptype_batch_send); // Max type
+ msg.addInt(2); // Min type
+ msg.addInt(3); // Max type
msg.addInt(2); // Preference weight
this._queueEvent(callback);
@@ -1718,89 +1718,143 @@ function CalcBlr(blr, xsqlda) {
blr.addByte(blr_eoc);
}
-function GetNullFor(type) {
- switch (type) {
- case SQL_VARYING:
- case SQL_NULL:
- case SQL_TEXT:
- return new SQLParamString(null);
- case SQL_DOUBLE:
- case SQL_FLOAT:
- case SQL_D_FLOAT:
- return new SQLParamDouble(null);
- case SQL_TYPE_DATE:
- case SQL_TYPE_TIME:
- case SQL_TIMESTAMP:
- return new SQLParamDate(null);
- case SQL_BLOB:
- case SQL_ARRAY:
- case SQL_QUAD:
- return new SQLParamQuad(null);
- case SQL_LONG:
- case SQL_SHORT:
- case SQL_INT64:
- case SQL_BOOLEAN:
- return new SQLParamInt(null);
- default:
- return null;
+Connection.prototype.executeStatement = function(transaction, statement, params, callback){
+
+ if (params instanceof Function) {
+ callback = params;
+ params = undefined;
}
-}
-function PrepareParams(params, input) {
- var value;
- var ret = new Array(params.length);
- for (var i = 0; i < params.length; i++) {
- value = params[i];
- switch (typeof value) {
- case 'number':
- if (value % 1 === 0) {
- if (value >= MIN_INT && value <= MAX_INT) {
- ret[i] = new SQLParamInt(value)
+ var self = this;
+ function PrepareParams(params, input, callback) {
+ var value, meta;
+ var ret = new Array(params.length);
+ var wait = params.length;
+
+ function done(){
+ wait--;
+ if (wait === 0) {
+ callback(ret);
+ }
+ }
+
+ function putBlobData(index, value, callback){
+ self.createBlob2(transaction,
+ function(err, blob){
+ var b;
+ if (Buffer.isBuffer(value)) {
+ b = value;
+ } else if (typeof value === 'string') {
+ b = new Buffer(value, DEFAULT_ENCODING)
} else {
- ret[i] = new SQLParamInt64(value)
+ b = new Buffer(JSON.stringify(value), DEFAULT_ENCODING)
+ }
+
+ var start = 0;
+ var end = 1024;
+ batch(callback);
+
+ function batch(callback){
+ if (b.length <= end) {
+ end = undefined; // get remaining bytes
+ }
+ self.batchSegments(blob, b.slice(start, end),
+ function (){
+ if (end === undefined) {
+ ret[index] = new SQLParamQuad(blob.oid);
+ self.closeBlob(blob, callback);
+ } else {
+ start += 1024;
+ end += 1024;
+ batch(callback);
+ }
+ }
+ )
}
- } else {
- ret[i] = new SQLParamDouble(value);
}
- break;
- case 'string':
- ret[i] = new SQLParamString(value);
- break;
- case 'boolean':
- ret[i] = new SQLParamBool(value);
- break;
- case 'undefined':
- ret[i] = GetNullFor(input[i].type);
- break;
- case 'object':
- if (value == null) {
- ret[i] = GetNullFor(input[i].type);
- break;
+ );
+ }
+
+ for (var i = 0; i < params.length; i++) {
+ value = params[i];
+ meta = input[i];
+
+ if (value == null) {
+ switch (meta.type) {
+ case SQL_VARYING:
+ case SQL_NULL:
+ case SQL_TEXT:
+ ret[i] = new SQLParamString(null);
+ break;
+ case SQL_DOUBLE:
+ case SQL_FLOAT:
+ case SQL_D_FLOAT:
+ ret[i] = new SQLParamDouble(null);
+ break;
+ case SQL_TYPE_DATE:
+ case SQL_TYPE_TIME:
+ case SQL_TIMESTAMP:
+ ret[i] = new SQLParamDate(null);
+ break;
+ case SQL_BLOB:
+ case SQL_ARRAY:
+ case SQL_QUAD:
+ ret[i] = new SQLParamQuad(null);
+ break;
+ case SQL_LONG:
+ case SQL_SHORT:
+ case SQL_INT64:
+ case SQL_BOOLEAN:
+ ret[i] = new SQLParamInt(null);
+ break;
+ default:
+ ret[i] = null;
}
- if (value instanceof Date) {
- ret[i] = new SQLParamDate(value);
- break;
+ done();
+ } else {
+ switch (meta.type) {
+ case SQL_BLOB:
+ putBlobData(i, value, done);
+ break;
+ case SQL_TIMESTAMP:
+ case SQL_TYPE_DATE:
+ case SQL_TYPE_TIME:
+ if (value instanceof Date) {
+ ret[i] = new SQLParamDate(value);
+ } else {
+ ret[i] = new SQLParamDate(new Date(value));
+ }
+ done();
+ break;
+ default:
+ switch (typeof value) {
+ case 'number':
+ if (value % 1 === 0) {
+ if (value >= MIN_INT && value <= MAX_INT) {
+ ret[i] = new SQLParamInt(value)
+ } else {
+ ret[i] = new SQLParamInt64(value)
+ }
+ } else {
+ ret[i] = new SQLParamDouble(value);
+ }
+ break;
+ case 'string':
+ ret[i] = new SQLParamString(value);
+ break;
+ case 'boolean':
+ ret[i] = new SQLParamBool(value);
+ break;
+ default:
+ throw new Error("Unexpected parametter");
+ }
+ done();
}
- default:
- throw new Error("Unexpected parametter");
+ }
}
}
- return ret;
-}
-Connection.prototype.executeStatement = function(transaction, statement, params, callback){
- var msg = this._msg;
- var blr = this._blr;
- msg.pos = 0;
- blr.pos = 0;
- if (params instanceof Function) {
- callback = params;
- params = null;
- }
- msg.addInt(op_execute);
- msg.addInt(statement.handle);
- msg.addInt(transaction.handle);
var input = statement.input;
if (input.length) {
if (!(params instanceof Array)) {
@@ -1813,20 +1867,45 @@ Connection.prototype.executeStatement = function(transaction, statement, params,
if (params === undefined || params.length != input.length) {
throw new Error("expected parametters: " + input.length);
}
- params = PrepareParams(params, input);
- CalcBlr(blr, params);
- msg.addBlr(blr);
- msg.addInt(0); // message number
- msg.addInt(1); // param count
- for(var i = 0; i < params.length; i++) {
- params[i].encode(msg);
- }
+ PrepareParams(params, input,
+ function(prms){
+
+ var msg = self._msg;
+ var blr = self._blr;
+ msg.pos = 0;
+ blr.pos = 0;
+
+ CalcBlr(blr, prms);
+
+ msg.addInt(op_execute);
+ msg.addInt(statement.handle);
+ msg.addInt(transaction.handle);
+
+ msg.addBlr(blr);
+ msg.addInt(0); // message number
+ msg.addInt(1); // param count
+ for(var i = 0; i < prms.length; i++) {
+ prms[i].encode(msg);
+ }
+ self._queueEvent(callback);
+ }
+ );
+
} else {
+ var msg = this._msg;
+ var blr = this._blr;
+ msg.pos = 0;
+ blr.pos = 0;
+
+ msg.addInt(op_execute);
+ msg.addInt(statement.handle);
+ msg.addInt(transaction.handle);
+
msg.addBlr(blr); // empty
msg.addInt(0); // message number
msg.addInt(0); // param count
+ this._queueEvent(callback);
}
- this._queueEvent(callback);
};
function fetchBlobs(statement, transaction, rows, callback) {
@@ -1861,7 +1940,12 @@ function fetchBlobs(statement, transaction, rows, callback) {
}
if (ret.handle == 2) { // ???
if (statement.output[col].subType == isc_blob_text) {
- rows.data[row][col] = buffer.toString(DEFAULT_ENCODING);
+ if (buffer) {
+ rows.data[row][col] = buffer.toString(DEFAULT_ENCODING);
+ } else {
+ rows.data[row][col] = null;
+ }
+
} else {
rows.data[row][col] = buffer
}
@@ -1986,4 +2070,28 @@ Connection.prototype.getSegment = function(blob, callback) {
msg.addInt(1024); // buffer length
msg.addInt(0); // ???
this._queueEvent(callback);
+};
+
+Connection.prototype.createBlob2 = function (transaction, callback) {
+ var msg = this._msg;
+ msg.pos = 0;
+ msg.addInt(op_create_blob2);
+ msg.addInt(0);
+ msg.addInt(transaction.handle);
+ msg.addInt(0);
+ msg.addInt(0);
+ this._queueEvent(callback);
+};
+
+Connection.prototype.batchSegments = function(blob, buffer, callback){
+ var msg = this._msg;
+ var blr = this._blr;
+ msg.pos = 0;
+ blr.pos = 0;
+ msg.addInt(op_batch_segments);
+ msg.addInt(blob.handle);
+ msg.addInt(buffer.length + 2);
+ blr.addBuffer(buffer);
+ msg.addBlr(blr);
+ this._queueEvent(callback);
};
View
20 lib/serialize.js
@@ -84,6 +84,13 @@ BlrWriter.prototype.addString = function (c, s, encoding) {
this.pos += len;
};
+BlrWriter.prototype.addBuffer = function (b) {
+ this.addSmall(b.length);
+ this.ensure(b.length);
+ b.copy(this.buffer, this.pos);
+ this.pos += b.length;
+};
+
/***************************************
*
* BLR Reader
@@ -201,7 +208,7 @@ XdrWriter.prototype.addUInt = function (value) {
this.pos += 4;
};
-XdrWriter.prototype.addString = function (s, encoding) {
+XdrWriter.prototype.addString = function(s, encoding) {
var len = Buffer.byteLength(s, encoding);
var alen = align(len);
this.ensure(alen + 4);
@@ -211,15 +218,15 @@ XdrWriter.prototype.addString = function (s, encoding) {
this.pos += alen;
};
-XdrWriter.prototype.addText = function (s, encoding) {
+XdrWriter.prototype.addText = function(s, encoding) {
var len = Buffer.byteLength(s, encoding);
var alen = align(len);
this.ensure(alen);
this.buffer.write(s, this.pos, len, encoding);
this.pos += alen;
};
-XdrWriter.prototype.addBlr = function (blr) {
+XdrWriter.prototype.addBlr = function(blr) {
var alen = align(blr.pos);
this.ensure(alen + 4);
this.buffer.writeInt32BE(blr.pos, this.pos);
@@ -228,10 +235,7 @@ XdrWriter.prototype.addBlr = function (blr) {
this.pos += alen;
};
-XdrWriter.prototype.getData = function () {
- //var buffer = new Buffer(this.pos);
- //this.buffer.copy(buffer, 0);
- //return buffer;
+XdrWriter.prototype.getData = function() {
return this.buffer.slice(0, this.pos);
};
@@ -248,7 +252,7 @@ XdrWriter.prototype.addQuad = function(quad) {
this.pos += 4;
b.writeInt32BE(quad.low, this.pos);
this.pos += 4;
-}
+};
/***************************************
*
View
2 package.json
@@ -1,6 +1,6 @@
{
"name": "node-firebird",
- "version": "0.1.0",
+ "version": "0.1.1",
"description": "Firebird client - pure javascript",
"keywords": [
"firebird",

0 comments on commit 9a99026

Please sign in to comment.
Something went wrong with that request. Please try again.