Commit 09e68144 by Konstantin Käfer

add blob support

parent 6e391c03
......@@ -2,6 +2,8 @@
#include <v8.h>
#include <node.h>
#include <node_events.h>
#include <node_buffer.h>
#include <node_version.h>
#include "macros.h"
#include "database.h"
......@@ -186,6 +188,10 @@ template <class T> T* Statement::Bind(const Arguments& args, int start) {
else if (args[i]->IsNull()) {
baton->parameters.push_back(new Data::Null());
}
else if (Buffer::HasInstance(args[i])) {
Local<Object> buffer = args[i]->ToObject();
baton->parameters.push_back(new Data::Blob(Buffer::Length(buffer), Buffer::Data(buffer)));
}
else if (args[i]->IsUndefined()) {
// Skip parameter position.
baton->parameters.push_back(NULL);
......@@ -219,19 +225,23 @@ bool Statement::Bind(const Data::Parameters parameters) {
switch (field->type) {
case SQLITE_INTEGER: {
status = sqlite3_bind_int(handle, i, ((Data::Integer*)field)->value);
status = sqlite3_bind_int(handle, i,
((Data::Integer*)field)->value);
} break;
case SQLITE_FLOAT: {
status = sqlite3_bind_double(handle, i, ((Data::Float*)field)->value);
status = sqlite3_bind_double(handle, i,
((Data::Float*)field)->value);
} break;
case SQLITE_TEXT: {
status = sqlite3_bind_text(
handle, i, ((Data::Text*)field)->value.c_str(),
status = sqlite3_bind_text(handle, i,
((Data::Text*)field)->value.c_str(),
((Data::Text*)field)->value.size(), SQLITE_TRANSIENT);
} break;
// case SQLITE_BLOB: {
//
// } break;
case SQLITE_BLOB: {
status = sqlite3_bind_blob(handle, i,
((Data::Blob*)field)->value,
((Data::Blob*)field)->length, SQLITE_TRANSIENT);
} break;
case SQLITE_NULL: {
status = sqlite3_bind_null(handle, i);
} break;
......@@ -566,9 +576,10 @@ Local<Array> Statement::RowToJS(Data::Row* row) {
case SQLITE_TEXT: {
result->Set(i, Local<String>(String::New(((Data::Text*)field)->value.c_str(), ((Data::Text*)field)->value.size())));
} break;
// case SQLITE_BLOB: {
// result->Set(i, Local<String>(String::New(((Data::Text*)field)->value.c_str())));
// } break;
case SQLITE_BLOB: {
Buffer *buffer = Buffer::New(((Data::Blob*)field)->value, ((Data::Blob*)field)->length);
result->Set(i, buffer->handle_);
} break;
case SQLITE_NULL: {
result->Set(i, Local<Value>::New(Null()));
} break;
......
......@@ -42,14 +42,14 @@ namespace Data {
struct Blob : Field {
Blob(size_t len, const void* val) : Field(SQLITE_BLOB), length(len) {
value = malloc(len);
value = (char*)malloc(len);
memcpy(value, val, len);
}
~Blob() {
free(value);
}
int length;
void* value;
char* value;
};
typedef Field Null;
......
......@@ -5,71 +5,44 @@ var sqlite3 = require('sqlite3'),
Buffer = require('buffer').Buffer;
// lots of elmo
var elmo = fs.readFileSync(__dirname + '/support/elmo.png', 'binary');
var elmo_str = elmo.toString('binary');
var elmo = fs.readFileSync(__dirname + '/support/elmo.png');
exports['Blob overflow test'] = function(beforeExit) {
var db = new sqlite3.Database('');
exports['blob test'] = function(beforeExit) {
var db = new sqlite3.Database(':memory:');
var total = 10;
var inserted = 0;
var retrieved = 0;
Step(
function() {
var next = this;
db.prepare('CREATE TABLE elmos (image BLOB);').run(next);
},
function() {
var group = this.group();
db.serialize(function() {
db.run('CREATE TABLE elmos (id INT, image BLOB)');
for (var i = 0; i < total; i++) {
var next = group();
db.prepare('INSERT INTO elmos (image) VALUES (?)', function(err, statement) {
assert.isUndefined(err);
statement.bind(1, elmo, function() {
statement.step(function(err) {
assert.isUndefined(err);
db.run('INSERT INTO elmos (id, image) VALUES (?, ?)', i, elmo, function(err) {
if (err) throw err;
inserted++;
next();
});
});
});
}
},
function() {
var next = this;
db.execute('SELECT COUNT(*) as amount FROM elmos', function(err, rows) {
assert.isUndefined(err);
assert.eql(rows[0].amount, total);
next();
});
},
function() {
var next = this;
db.prepare('SELECT image FROM elmos;', function(err, statement) {
assert.isUndefined(err);
fetch();
function fetch() {
statement.step(function(err, row) {
assert.isUndefined(err);
if (row) {
// Not using assert.equal here because it's image data
// and we don't want that in the command line.
assert.ok(elmo_str === row.image);
retrieved++;
fetch();
db.all('SELECT id, image FROM elmos ORDER BY id', function(err, rows) {
if (err) throw err;
for (var i = 0; i < rows.length; i++) {
assert.ok(Buffer.isBuffer(rows[i][1]));
assert.ok(elmo.length, rows[i][1]);
for (var j = 0; j < elmo.length; j++) {
if (elmo[j] !== rows[i][1][j]) {
assert.ok(false, "Wrong byte");
}
else {
next();
}
});
retrieved++;
}
});
}
);
});
beforeExit(function() {
assert.eql(inserted, total);
assert.eql(retrieved, total);
assert.equal(inserted, total);
assert.equal(retrieved, total);
})
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment