Skip to content

Commit b96f792

Browse files
committedMay 20, 2010
Replace with up to date postgres-pure driver.
This is the one extracted from node-persistence and made to run on heroku's system.
1 parent ecbbc4b commit b96f792

File tree

7 files changed

+1274
-857
lines changed

7 files changed

+1274
-857
lines changed
 

‎README.markdown

+2-13
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,6 @@
33
This library is a implementation of the PostgreSQL backend/frontend protocol in javascript.
44
It uses the node.js tcp and event libraries. A javascript md5 library is included for servers that require md5 password hashing (this is default).
55

6-
## Example use
7-
8-
var sys = require("sys");
9-
var Postgres = require('postgres.js');
10-
11-
function onLoad() {
12-
var db = new Postgres.Connection("database", "username", "password");
13-
db.query("SELECT * FROM sometable", function (data) {
14-
sys.p(data);
15-
});
16-
db.close();
17-
}
18-
6+
This is using the api from node-persistence and is used by sousaball.
197

8+
See test.js for sample usage.

‎lib/buffer_extras.js

+218
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
/*
2+
Copyright (c) 2010 Tim Caswell <tim@creationix.com>
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy
5+
of this software and associated documentation files (the "Software"), to deal
6+
in the Software without restriction, including without limitation the rights
7+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is
9+
furnished to do so, subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all
12+
copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
SOFTWARE.
21+
*/
22+
23+
var Buffer = module.exports = require('buffer').Buffer;
24+
var proto = Buffer.prototype;
25+
26+
// Cleans the buffer to be all zeroes
27+
proto.zeroOut = function zeroOut() {
28+
for (var i = 0, l = this.length; i < l; i++) {
29+
this[i] = 0;
30+
}
31+
};
32+
33+
// Writes a 32 bit integer at offset
34+
proto.int32Write = function int32Write(number, offset) {
35+
offset = offset || 0;
36+
var unsigned = (number < 0) ? (number + 0x100000000) : number;
37+
this[offset] = Math.floor(unsigned / 0xffffff);
38+
unsigned &= 0xffffff;
39+
this[offset + 1] = Math.floor(unsigned / 0xffff);
40+
unsigned &= 0xffff;
41+
this[offset + 2] = Math.floor(unsigned / 0xff);
42+
unsigned &= 0xff;
43+
this[offset + 3] = Math.floor(unsigned);
44+
};
45+
46+
// Writes a 16 bit integer at offset
47+
proto.int16Write = function int16Write(number, offset) {
48+
offset = offset || 0;
49+
var unsigned = (number < 0) ? (number + 0x10000) : number;
50+
this[offset] = Math.floor(unsigned / 0xff);
51+
unsigned &= 0xff;
52+
this[offset + 1] = Math.floor(unsigned);
53+
}
54+
55+
// Reads a 32 bit integer from offset
56+
proto.int32Read = function int32Read(offset) {
57+
offset = offset || 0;
58+
var unsigned = this[offset] * 0x1000000 +
59+
this[offset + 1] * 0x10000 +
60+
this[offset + 2] * 0x100 +
61+
this[offset + 3];
62+
return (unsigned & 0x80000000) ? (unsigned - 0x100000000) : unsigned
63+
};
64+
65+
// Reads a 32 bit integer from offset
66+
proto.int16Read = function int16Read(offset) {
67+
offset = offset || 0;
68+
var unsigned = this[offset] * 0x100 +
69+
this[offset + 1];
70+
return (unsigned & 0x8000) ? (unsigned - 0x10000) : unsigned
71+
};
72+
73+
Buffer.fromString = function fromString(string) {
74+
var b = new Buffer(Buffer.byteLength(string));
75+
b.write(string, 'utf8');
76+
return b;
77+
}
78+
79+
Buffer.makeWriter = function makeWriter() {
80+
var data = [];
81+
var writer;
82+
var push = {
83+
int32: function pushInt32(number) {
84+
var b = new Buffer(4);
85+
b.int32Write(number);
86+
data.push(b);
87+
return writer;
88+
},
89+
int16: function pushInt16(number) {
90+
var b = new Buffer(2);
91+
b.int16Write(number);
92+
data.push(b);
93+
return writer;
94+
},
95+
string: function pushString(string) {
96+
data.push(Buffer.fromString(string));
97+
return writer;
98+
},
99+
cstring: function pushCstring(string) {
100+
data.push(Buffer.fromString(string + "\0"));
101+
return writer;
102+
},
103+
multicstring: function pushMulticstring(fields) {
104+
data.push(Buffer.fromString(fields.join("\0") + "\0\0"));
105+
return writer;
106+
},
107+
hash: function pushHash(hash) {
108+
var keys = Object.keys(hash);
109+
var pairs = [];
110+
for (var i = 0, l = keys.length; i < l; i++) {
111+
var key = keys[i];
112+
pairs.push(key + "\0" + hash[key] + "\0");
113+
}
114+
data.push(Buffer.fromString(pairs.join("") + "\0"));
115+
return writer;
116+
}
117+
};
118+
writer = {
119+
data: data,
120+
push: push,
121+
122+
// Convert an array of buffers into a single buffer using memcopy
123+
toBuffer: function toBuffer() {
124+
var total = 0;
125+
var i, l = data.length;
126+
for (i = 0; i < l; i++) {
127+
total += data[i].length;
128+
}
129+
var b = new Buffer(total);
130+
var offset = 0;
131+
for (i = 0; i < l; i++) {
132+
data[i].copy(b, offset);
133+
offset += data[i].length;
134+
}
135+
return b;
136+
}
137+
};
138+
return writer;
139+
}
140+
141+
proto.toReader = function toReader() {
142+
var offset = 0, length = this.length, buffer = this;
143+
return {
144+
empty: function empty() {
145+
return offset >= length;
146+
},
147+
int32: function shiftInt32() {
148+
var number = buffer.int32Read(offset);
149+
offset += 4;
150+
return number;
151+
},
152+
int16: function shiftInt16() {
153+
var number = buffer.int16Read(offset);
154+
offset += 2;
155+
return number;
156+
},
157+
buffer: function shiftBuffer(length) {
158+
var b = buffer.slice(offset, offset + length);
159+
offset += length;
160+
return b;
161+
},
162+
string: function shiftString(length) {
163+
var string = buffer.toString('utf8', offset, offset + length);
164+
offset += length;
165+
return string;
166+
},
167+
cstring: function shiftCstring() {
168+
var end = offset;
169+
while (buffer[end] > 0 && end < length) { end++; }
170+
var string = buffer.toString('utf8', offset, end);
171+
offset = end + 1;
172+
return string;
173+
},
174+
multicstring: function shiftMulticstring() {
175+
var fields = [];
176+
while (buffer[offset] > 0) {
177+
fields.push(this.cstring());
178+
}
179+
offset++;
180+
return fields;
181+
},
182+
hash: function shiftHash() {
183+
var hash = {};
184+
while (buffer[offset] > 0) {
185+
hash[this.cstring()] = this.cstring();
186+
}
187+
offset++;
188+
return hash;
189+
}
190+
}
191+
};
192+
193+
// Test It
194+
// var sys = require('sys');
195+
//
196+
// var w = Buffer.makeWriter();
197+
// w.push.int32(305419896);
198+
// w.push.int16(4660);
199+
// w.push.string("12345");
200+
// w.push.cstring("Héllø Wø®l∂");
201+
// w.push.multicstring(["Hello", "World"]);
202+
// w.push.hash({name: "Tim", age: "28"});
203+
// w.push.int32(0x12345678);
204+
// w.push.int16(0x1234);
205+
// var b = w.toBuffer();
206+
// // sys.p(b);
207+
// var r = b.toReader();
208+
// sys.p([
209+
// r.int32(),
210+
// r.int16(),
211+
// r.string(5),
212+
// r.cstring(),
213+
// r.multicstring(),
214+
// r.hash(),
215+
// r.int32(),
216+
// r.int16()
217+
// ]);
218+
//

‎postgres-js/md5.js ‎lib/md5.js

+381-381
Large diffs are not rendered by default.

‎lib/postgres-pure.js

+451
Large diffs are not rendered by default.

‎lib/sql.js

+222
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
// Escape of values from native to SQL string.
2+
function sql_escape(value) {
3+
if (value === null) {
4+
return "NULL";
5+
}
6+
if (value === true) {
7+
return "TRUE";
8+
}
9+
if (value === false) {
10+
return "FALSE";
11+
}
12+
if (value.constructor.name === 'String') {
13+
return "'" + value.replace("'", "''") + "'";
14+
}
15+
return value.toString();
16+
}
17+
18+
// Fill in the placeholders with native values
19+
function merge(sql, parameters) {
20+
if (parameters.length === 0) {
21+
return sql;
22+
}
23+
if (parameters.length === 1 && parameters[0].constructor.name === 'Object') {
24+
parameters = parameters[0];
25+
// Named parameters
26+
for (var key in parameters) {
27+
if (parameters.hasOwnProperty(key)) {
28+
sql = sql.replace(":" + key, sql_escape(parameters[key]));
29+
}
30+
}
31+
} else {
32+
if (parameters.length === 1 && parameters[0].constructor.name === 'Array') {
33+
parameters = parameters[0];
34+
}
35+
// ordered parameters
36+
parameters.forEach(function (param) {
37+
sql = sql.replace("?", sql_escape(param));
38+
});
39+
}
40+
return sql;
41+
}
42+
43+
// Converter between JS types and SQL data types
44+
function js_to_sql(class) {
45+
if (class === String) {
46+
return 'text';
47+
}
48+
if (class === Number) {
49+
return 'integer';
50+
}
51+
if (class === Boolean) {
52+
return 'bool';
53+
}
54+
throw "Unknown type " + class;
55+
}
56+
57+
// Convert a condition hash/array to a proper SQL where clause.
58+
function condition_to_sql(condition, value) {
59+
var operator,
60+
p = condition.indexOf(' ');
61+
if (p === -1) {
62+
return condition + " = " + sql_escape(value);
63+
}
64+
operator = condition.substr(p + 1);
65+
condition = condition.substr(0, p);
66+
if (['<', '>', '=', '<=', '>=', '!=', '<>'].indexOf(operator) >= 0) {
67+
return condition + " " + operator + " " + sql_escape(value);
68+
}
69+
if (operator === '%') {
70+
return condition + " LIKE " + sql_escape(value);
71+
}
72+
sys.debug(operator);
73+
throw "Invalid operator " + operator;
74+
}
75+
76+
// overrides needs to contain at least the following
77+
// index_col: the name of the special index column rowid in sqlite and oid in postgres
78+
// do_insert: function (data, keys, values, callback)
79+
// do_update: function (data, pairs, callback)
80+
81+
function Store(conn, name, columns, overrides) {
82+
var key,
83+
types = [];
84+
85+
this.name = name;
86+
this.conn = conn;
87+
88+
if (overrides.types) {
89+
types = overrides.types;
90+
delete overrides.types;
91+
}
92+
93+
if (columns) {
94+
for (key in columns) {
95+
if (columns.hasOwnProperty(key)) {
96+
types.push(key + " " + js_to_sql(columns[key]));
97+
}
98+
}
99+
100+
conn.execute("CREATE TABLE " + name + "(" + types.join(", ") +")", function () {});
101+
}
102+
103+
if (overrides) {
104+
var self = this;
105+
Object.keys(overrides).forEach(function (key) {
106+
self[key] = overrides[key];
107+
});
108+
}
109+
110+
111+
}
112+
Store.prototype = {
113+
114+
get: function (id, callback) {
115+
this.conn.query(
116+
"SELECT " + this.index_col + " AS _id, * FROM " + this.name + " WHERE " + this.index_col + " = ?", id,
117+
function (data) {
118+
callback(data[0]);
119+
}
120+
);
121+
},
122+
123+
find: function (conditions, row_callback, callback) {
124+
// row_callback is optional
125+
if (typeof callback === 'undefined') {
126+
callback = row_callback;
127+
row_callback = false;
128+
}
129+
var sql;
130+
// Shortcut if there are no conditions.
131+
if (conditions === undefined || conditions.length === 0) {
132+
return this.all(callback);
133+
}
134+
135+
if (conditions.constructor.name !== 'Array') {
136+
conditions = [conditions];
137+
}
138+
139+
sql = "SELECT " + this.index_col + " AS _id, * FROM " + this.name + " WHERE " +
140+
conditions.map(function (group) {
141+
var ands = [], key;
142+
for (key in group) {
143+
if (group.hasOwnProperty(key)) {
144+
ands.push(condition_to_sql(key, group[key]));
145+
}
146+
}
147+
return "(" + ands.join(" AND ") + ")";
148+
}).join(" OR ");
149+
150+
if (row_callback) {
151+
this.conn.query(sql, row_callback, callback);
152+
}
153+
this.conn.query(sql, callback);
154+
},
155+
156+
each: function (row_callback, callback) {
157+
return this.conn.query("SELECT " + this.index_col + " AS _id, * FROM " + this.name, row_callback, callback);
158+
},
159+
160+
all: function (callback) {
161+
return this.conn.query("SELECT " + this.index_col + " AS _id, * FROM " + this.name, callback);
162+
},
163+
164+
do_update: function (data, pairs, callback) {
165+
this.conn.execute("UPDATE " + this.name +
166+
" SET " + pairs.join(", ") +
167+
" WHERE " + this.index_col + " = " + sql_escape(data._id),
168+
function () {
169+
callback();
170+
}
171+
);
172+
},
173+
174+
// Save a data object to the database. If it already has an _id do an update.
175+
save: function (data, callback) {
176+
var keys = [],
177+
values = [],
178+
pairs = [],
179+
key;
180+
181+
if (data._id) {
182+
for (key in data) {
183+
if (data.hasOwnProperty(key) && key !== '_id') {
184+
pairs.push(key + " = " + sql_escape(data[key]));
185+
}
186+
}
187+
this.do_update(data, pairs, callback);
188+
} else {
189+
for (key in data) {
190+
if (data.hasOwnProperty(key)) {
191+
keys.push(key);
192+
values.push(sql_escape(data[key]));
193+
}
194+
}
195+
this.do_insert(data, keys, values, callback);
196+
}
197+
},
198+
199+
// Remove an entry from the database and remove the _id from the data object.
200+
remove: function (data, callback) {
201+
if (typeof data === 'number') {
202+
data = {_id: data};
203+
}
204+
this.conn.execute("DELETE FROM " + this.name +
205+
" WHERE " + this.index_col + " = " + sql_escape(data._id),
206+
function () {
207+
delete data._id;
208+
callback()
209+
}
210+
);
211+
},
212+
213+
nuke: function (callback) {
214+
this.conn.query("DELETE FROM " + this.name, callback);
215+
}
216+
217+
};
218+
219+
exports.merge = merge;
220+
exports.Store = Store;
221+
222+

‎postgres-js/bits.js

-147
This file was deleted.

‎postgres.js

-316
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.