Skip to content

Commit 6802005

Browse files
committed
more datatypes
1 parent 3c1c312 commit 6802005

File tree

5 files changed

+120
-8
lines changed

5 files changed

+120
-8
lines changed

src/connection.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,24 @@ int Connection::SetValuesOnStatement(oracle::occi::Statement* stmt, std::vector<
8282
for (std::vector<value_t*>::iterator iterator = values.begin(), end = values.end(); iterator != end; ++iterator, index++) {
8383
value_t* val = *iterator;
8484
switch(val->type) {
85+
case VALUE_TYPE_NULL:
86+
stmt->setNull(index, oracle::occi::OCCISTRING);
87+
break;
8588
case VALUE_TYPE_STRING:
8689
stmt->setString(index, *((std::string*)val->value));
8790
break;
91+
case VALUE_TYPE_NUMBER:
92+
stmt->setNumber(index, *((oracle::occi::Number*)val->value));
93+
break;
94+
case VALUE_TYPE_DATE:
95+
stmt->setDate(index, *((oracle::occi::Date*)val->value));
96+
break;
8897
case VALUE_TYPE_OUTPUT:
8998
stmt->registerOutParam(index, oracle::occi::OCCIINT);
9099
outputParam = index;
91100
break;
92101
default:
93-
throw NodeOracleException("Unhandled value type");
102+
throw NodeOracleException("SetValuesOnStatement: Unhandled value type");
94103
}
95104
}
96105
return outputParam;

src/connection.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Connection : ObjectWrap {
2828
~Connection();
2929

3030
void setConnection(oracle::occi::Environment* environment, oracle::occi::Connection* connection);
31+
oracle::occi::Environment* getEnvironment() { return m_environment; }
3132

3233
private:
3334
static int SetValuesOnStatement(oracle::occi::Statement* stmt, std::vector<value_t*> &values);

src/executeBaton.cpp

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "executeBaton.h"
33
#include "outParam.h"
44
#include "nodeOracleException.h"
5+
#include "connection.h"
56

67
ExecuteBaton::ExecuteBaton(Connection* connection, const char* sql, v8::Local<v8::Array>* values, v8::Handle<v8::Function>* callback) {
78
this->connection = connection;
@@ -38,23 +39,70 @@ ExecuteBaton::~ExecuteBaton() {
3839
if(error) delete error;
3940
}
4041

42+
double CallDateMethod(v8::Local<v8::Date> date, const char* methodName) {
43+
Handle<Value> args[0];
44+
Local<Value> result = Local<Function>::Cast(date->Get(String::New(methodName)))->Call(date, 0, args);
45+
return Local<Number>::Cast(result)->Value();
46+
}
47+
48+
oracle::occi::Date* V8DateToOcciDate(oracle::occi::Environment* env, v8::Local<v8::Date> val) {
49+
int year = CallDateMethod(val, "getFullYear");
50+
int month = CallDateMethod(val, "getMonth") + 1;
51+
int day = CallDateMethod(val, "getDate");
52+
int hours = CallDateMethod(val, "getHours");
53+
int minutes = CallDateMethod(val, "getMinutes");
54+
int seconds = CallDateMethod(val, "getSeconds");
55+
oracle::occi::Date* d = new oracle::occi::Date(env, year, month, day, hours, minutes, seconds);
56+
return d;
57+
}
58+
4159
void ExecuteBaton::CopyValuesToBaton(ExecuteBaton* baton, v8::Local<v8::Array>* values) {
4260
for(uint32_t i=0; i<(*values)->Length(); i++) {
4361
v8::Local<v8::Value> val = (*values)->Get(i);
4462

4563
value_t *value = new value_t();
46-
if(val->IsString()) {
64+
65+
// null
66+
if(val->IsNull()) {
67+
value->type = VALUE_TYPE_NULL;
68+
value->value = NULL;
69+
baton->values.push_back(value);
70+
}
71+
72+
// string
73+
else if(val->IsString()) {
4774
v8::String::AsciiValue asciiVal(val);
4875
value->type = VALUE_TYPE_STRING;
4976
value->value = new std::string(*asciiVal);
5077
baton->values.push_back(value);
51-
} else if(val->IsObject() && val->ToObject()->FindInstanceInPrototypeChain(OutParam::constructorTemplate) != v8::Null()) {
78+
}
79+
80+
// date
81+
else if(val->IsDate()) {
82+
value->type = VALUE_TYPE_DATE;
83+
value->value = V8DateToOcciDate(baton->connection->getEnvironment(), v8::Date::Cast(*val));
84+
baton->values.push_back(value);
85+
}
86+
87+
// number
88+
else if(val->IsNumber()) {
89+
value->type = VALUE_TYPE_NUMBER;
90+
double d = v8::Number::Cast(*val)->Value();
91+
value->value = new oracle::occi::Number(d);
92+
baton->values.push_back(value);
93+
}
94+
95+
// output
96+
else if(val->IsObject() && val->ToObject()->FindInstanceInPrototypeChain(OutParam::constructorTemplate) != v8::Null()) {
5297
value->type = VALUE_TYPE_OUTPUT;
5398
value->value = NULL;
5499
baton->values.push_back(value);
55-
} else {
100+
}
101+
102+
// unhandled type
103+
else {
56104
std::ostringstream message;
57-
message << "Unhandled value type";
105+
message << "CopyValuesToBaton: Unhandled value type";
58106
throw NodeOracleException(message.str());
59107
}
60108
}

src/executeBaton.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ class Connection;
1414
#include <stdlib.h>
1515

1616
enum {
17+
VALUE_TYPE_NULL,
1718
VALUE_TYPE_OUTPUT,
1819
VALUE_TYPE_STRING,
19-
VALUE_TYPE_NUMBER
20+
VALUE_TYPE_NUMBER,
21+
VALUE_TYPE_DATE
2022
};
2123

2224
struct column_t {

tests/integration.js

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,26 @@
1515
SELECT person_seq.nextval INTO :new.id FROM dual;
1616
END;
1717
/
18+
CREATE TABLE datatype_test (
19+
id INTEGER PRIMARY KEY,
20+
tvarchar2 VARCHAR2(255),
21+
tnvarchar2 NVARCHAR2(255),
22+
tchar CHAR(255),
23+
tnchar NCHAR(255),
24+
tnumber NUMBER(10,5),
25+
tdate DATE,
26+
ttimestamp TIMESTAMP,
27+
tclob CLOB,
28+
tnclob NCLOB,
29+
tblob BLOB,
30+
tbfile BFILE,
31+
txmltype XMLType);
32+
CREATE SEQUENCE datatype_test_seq START WITH 1 INCREMENT BY 1 NOMAXVALUE;
33+
CREATE TRIGGER datatype_test_pk_trigger BEFORE INSERT ON datatype_test FOR EACH row
34+
BEGIN
35+
SELECT datatype_test_seq.nextval INTO :new.id FROM dual;
36+
END;
37+
/
1838
*/
1939

2040
var nodeunit = require("nodeunit");
@@ -32,8 +52,11 @@ exports['IntegrationTest'] = nodeunit.testCase({
3252
self.connection = connection;
3353
self.connection.execute("DELETE FROM person", [], function(err, results) {
3454
if(err) { callback(err); return; }
35-
//console.log("rows deleted: ", results);
36-
callback();
55+
self.connection.execute("DELETE FROM datatype_test", [], function(err, results) {
56+
if(err) { callback(err); return; }
57+
//console.log("rows deleted: ", results);
58+
callback();
59+
});
3760
});
3861
});
3962
},
@@ -69,5 +92,34 @@ exports['IntegrationTest'] = nodeunit.testCase({
6992
test.ok(results.returnParam > 0);
7093
test.done();
7194
});
95+
},
96+
97+
"datatypes": function(test) {
98+
var self = this;
99+
var date1 = new Date(2011, 10, 30, 1, 2, 3);
100+
var date2 = new Date(2011, 11, 1, 1, 2, 3);
101+
self.connection.execute(
102+
"INSERT INTO datatype_test "
103+
+ "(tvarchar2, tnvarchar2, tchar, tnchar, tnumber, tdate, ttimestamp, tclob, tnclob, tblob, txmltype) VALUES "
104+
+ "(:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11) RETURNING id INTO :12",
105+
[
106+
"tvarchar2 value",
107+
"tnvarchar2 value",
108+
"tchar value",
109+
"tnchar value",
110+
42.5,
111+
date1,
112+
date2,
113+
"tclob value",
114+
"tnclob value",
115+
null, //new Buffer("tblob value"),
116+
"<xmlData></xmlData>",
117+
new oracle.OutParam()
118+
],
119+
function(err, results) {
120+
if(err) { console.error(err); return; }
121+
test.ok(results.returnParam > 0);
122+
test.done();
123+
});
72124
}
73125
});

0 commit comments

Comments
 (0)