Permalink
Browse files

more datatypes

  • Loading branch information...
1 parent 3c1c312 commit 6802005bdc615e018c12773c5a72d2059276c962 @joeferner committed Dec 21, 2011
Showing with 120 additions and 8 deletions.
  1. +10 −1 src/connection.cpp
  2. +1 −0 src/connection.h
  3. +52 −4 src/executeBaton.cpp
  4. +3 −1 src/executeBaton.h
  5. +54 −2 tests/integration.js
View
@@ -82,15 +82,24 @@ int Connection::SetValuesOnStatement(oracle::occi::Statement* stmt, std::vector<
for (std::vector<value_t*>::iterator iterator = values.begin(), end = values.end(); iterator != end; ++iterator, index++) {
value_t* val = *iterator;
switch(val->type) {
+ case VALUE_TYPE_NULL:
+ stmt->setNull(index, oracle::occi::OCCISTRING);
+ break;
case VALUE_TYPE_STRING:
stmt->setString(index, *((std::string*)val->value));
break;
+ case VALUE_TYPE_NUMBER:
+ stmt->setNumber(index, *((oracle::occi::Number*)val->value));
+ break;
+ case VALUE_TYPE_DATE:
+ stmt->setDate(index, *((oracle::occi::Date*)val->value));
+ break;
case VALUE_TYPE_OUTPUT:
stmt->registerOutParam(index, oracle::occi::OCCIINT);
outputParam = index;
break;
default:
- throw NodeOracleException("Unhandled value type");
+ throw NodeOracleException("SetValuesOnStatement: Unhandled value type");
}
}
return outputParam;
View
@@ -28,6 +28,7 @@ class Connection : ObjectWrap {
~Connection();
void setConnection(oracle::occi::Environment* environment, oracle::occi::Connection* connection);
+ oracle::occi::Environment* getEnvironment() { return m_environment; }
private:
static int SetValuesOnStatement(oracle::occi::Statement* stmt, std::vector<value_t*> &values);
View
@@ -2,6 +2,7 @@
#include "executeBaton.h"
#include "outParam.h"
#include "nodeOracleException.h"
+#include "connection.h"
ExecuteBaton::ExecuteBaton(Connection* connection, const char* sql, v8::Local<v8::Array>* values, v8::Handle<v8::Function>* callback) {
this->connection = connection;
@@ -38,23 +39,70 @@ ExecuteBaton::~ExecuteBaton() {
if(error) delete error;
}
+double CallDateMethod(v8::Local<v8::Date> date, const char* methodName) {
+ Handle<Value> args[0];
+ Local<Value> result = Local<Function>::Cast(date->Get(String::New(methodName)))->Call(date, 0, args);
+ return Local<Number>::Cast(result)->Value();
+}
+
+oracle::occi::Date* V8DateToOcciDate(oracle::occi::Environment* env, v8::Local<v8::Date> val) {
+ int year = CallDateMethod(val, "getFullYear");
+ int month = CallDateMethod(val, "getMonth") + 1;
+ int day = CallDateMethod(val, "getDate");
+ int hours = CallDateMethod(val, "getHours");
+ int minutes = CallDateMethod(val, "getMinutes");
+ int seconds = CallDateMethod(val, "getSeconds");
+ oracle::occi::Date* d = new oracle::occi::Date(env, year, month, day, hours, minutes, seconds);
+ return d;
+}
+
void ExecuteBaton::CopyValuesToBaton(ExecuteBaton* baton, v8::Local<v8::Array>* values) {
for(uint32_t i=0; i<(*values)->Length(); i++) {
v8::Local<v8::Value> val = (*values)->Get(i);
value_t *value = new value_t();
- if(val->IsString()) {
+
+ // null
+ if(val->IsNull()) {
+ value->type = VALUE_TYPE_NULL;
+ value->value = NULL;
+ baton->values.push_back(value);
+ }
+
+ // string
+ else if(val->IsString()) {
v8::String::AsciiValue asciiVal(val);
value->type = VALUE_TYPE_STRING;
value->value = new std::string(*asciiVal);
baton->values.push_back(value);
- } else if(val->IsObject() && val->ToObject()->FindInstanceInPrototypeChain(OutParam::constructorTemplate) != v8::Null()) {
+ }
+
+ // date
+ else if(val->IsDate()) {
+ value->type = VALUE_TYPE_DATE;
+ value->value = V8DateToOcciDate(baton->connection->getEnvironment(), v8::Date::Cast(*val));
+ baton->values.push_back(value);
+ }
+
+ // number
+ else if(val->IsNumber()) {
+ value->type = VALUE_TYPE_NUMBER;
+ double d = v8::Number::Cast(*val)->Value();
+ value->value = new oracle::occi::Number(d);
+ baton->values.push_back(value);
+ }
+
+ // output
+ else if(val->IsObject() && val->ToObject()->FindInstanceInPrototypeChain(OutParam::constructorTemplate) != v8::Null()) {
value->type = VALUE_TYPE_OUTPUT;
value->value = NULL;
baton->values.push_back(value);
- } else {
+ }
+
+ // unhandled type
+ else {
std::ostringstream message;
- message << "Unhandled value type";
+ message << "CopyValuesToBaton: Unhandled value type";
throw NodeOracleException(message.str());
}
}
View
@@ -14,9 +14,11 @@ class Connection;
#include <stdlib.h>
enum {
+ VALUE_TYPE_NULL,
VALUE_TYPE_OUTPUT,
VALUE_TYPE_STRING,
- VALUE_TYPE_NUMBER
+ VALUE_TYPE_NUMBER,
+ VALUE_TYPE_DATE
};
struct column_t {
View
@@ -15,6 +15,26 @@
SELECT person_seq.nextval INTO :new.id FROM dual;
END;
/
+ CREATE TABLE datatype_test (
+ id INTEGER PRIMARY KEY,
+ tvarchar2 VARCHAR2(255),
+ tnvarchar2 NVARCHAR2(255),
+ tchar CHAR(255),
+ tnchar NCHAR(255),
+ tnumber NUMBER(10,5),
+ tdate DATE,
+ ttimestamp TIMESTAMP,
+ tclob CLOB,
+ tnclob NCLOB,
+ tblob BLOB,
+ tbfile BFILE,
+ txmltype XMLType);
+ CREATE SEQUENCE datatype_test_seq START WITH 1 INCREMENT BY 1 NOMAXVALUE;
+ CREATE TRIGGER datatype_test_pk_trigger BEFORE INSERT ON datatype_test FOR EACH row
+ BEGIN
+ SELECT datatype_test_seq.nextval INTO :new.id FROM dual;
+ END;
+ /
*/
var nodeunit = require("nodeunit");
@@ -32,8 +52,11 @@ exports['IntegrationTest'] = nodeunit.testCase({
self.connection = connection;
self.connection.execute("DELETE FROM person", [], function(err, results) {
if(err) { callback(err); return; }
- //console.log("rows deleted: ", results);
- callback();
+ self.connection.execute("DELETE FROM datatype_test", [], function(err, results) {
+ if(err) { callback(err); return; }
+ //console.log("rows deleted: ", results);
+ callback();
+ });
});
});
},
@@ -69,5 +92,34 @@ exports['IntegrationTest'] = nodeunit.testCase({
test.ok(results.returnParam > 0);
test.done();
});
+ },
+
+ "datatypes": function(test) {
+ var self = this;
+ var date1 = new Date(2011, 10, 30, 1, 2, 3);
+ var date2 = new Date(2011, 11, 1, 1, 2, 3);
+ self.connection.execute(
+ "INSERT INTO datatype_test "
+ + "(tvarchar2, tnvarchar2, tchar, tnchar, tnumber, tdate, ttimestamp, tclob, tnclob, tblob, txmltype) VALUES "
+ + "(:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11) RETURNING id INTO :12",
+ [
+ "tvarchar2 value",
+ "tnvarchar2 value",
+ "tchar value",
+ "tnchar value",
+ 42.5,
+ date1,
+ date2,
+ "tclob value",
+ "tnclob value",
+ null, //new Buffer("tblob value"),
+ "<xmlData></xmlData>",
+ new oracle.OutParam()
+ ],
+ function(err, results) {
+ if(err) { console.error(err); return; }
+ test.ok(results.returnParam > 0);
+ test.done();
+ });
}
});

0 comments on commit 6802005

Please sign in to comment.