不要怂,就是干,撸起袖子干!

Commit 789a6864 by Sascha Depold

removed node-mysql and added nodejs-mysql-native

1 parent d57a18f2
/*
node-mysql
node-mysql is pure Javascript MySQL network driver for [node.js](http://nodejs.org/)
*/
var sys = require('sys');
var events = require('events');
var result = require('./mysql/result');
var types = require('./mysql/types');
var utils = require('./mysql/utils');
var errors = require('./mysql/errors');
var Promise = require('./mysql/node-promise').Promise;
var Protocol = require('./mysql/protocol').Protocol;
var constants = require('./mysql/constants')
exports.constants = constants;
exports.Time = types.Time;
exports.quote = types.quote;
exports.constants = constants;
var Connection = function(hostname, username, password, dbname, port) {
events.EventEmitter.call(this);
this.protocol = undefined;
this.active = false;
this.connect_parameter = Array.prototype.slice.call(arguments);
this.last_error = undefined;
this.sqlstate = undefined;
this._timeout = undefined;
this.defaultErrback = function(error) {
sys.puts("MySQL error: "+error);
}
}
sys.inherits(Connection, events.EventEmitter);
exports.Connection = Connection;
Connection.prototype.connect = function(callback, errback) {
this.protocol = new Protocol(this.connect_parameter[0], this.connect_parameter[4]);
if(this._timeout) this.protocol.timeout(this._timeout);
this.protocol.addListener('connect', utils.scope(this, function() {
this.active = false;
this.emit('connect');
this.protocol.authenticate(this.connect_parameter[1],
this.connect_parameter[2],
this.connect_parameter[3],
(this.local_infile ? constants.client.LOCAL_FILES : 0),
'utf8_general_ci'
)
.addCallback(callback)
.addErrback(errback || this.defaultErrback);
}));
this.protocol.addListener('close', utils.scope(this, function() {
this.active = false;
this.emit('close');
}));
this.protocol.addListener('authorized', utils.scope(this, function() {
this.active = true;
this.emit('authorized');
}));
this.protocol.addListener('authorize error', utils.scope(this, function() {
this.active = false;
this.emit('authorize error');
}));
}
Connection.prototype.close = function() {
this.protocol.close();
}
Connection.prototype.timeout = function(msec) {
if(msec) {
this._timeout = msec;
if(this.protocol) this.protocol.timeout(this._timeout);
}
return this._timeout;
}
// Set autocommit mode
Connection.prototype.autocommit = function(flag, callback, errback) {
this.query("set autocommit="+(flag ? "1" : "0"), callback, (errback || this.defaultErrback));
}
Connection.prototype.query = function(sql, callback, errback) {
var sql = this.extract_placeholder(sql);
if(sql.constructor==errors.ClientError.prototype.constructor) {
(errback || this.defaultErrback)(sql);
return;
}
this.protocol.query_command(sql)
.addCallback(utils.scope(this, function(nfields) {
if(nfields) {
this.protocol.retr_fields(nfields)
.addCallback(utils.scope(this, function(fields) {
this.fields = fields;
this.get_result()
.addCallback(utils.scope(this, function(rows) {
this.server_status = this.protocol.server_status;
try {
if(callback) callback(rows);
}
catch(error) {
(errback || this.defaultErrback)(error);
}
}))
.addErrback(errback || this.defaultErrback);
}))
.addErrback(errback || this.defaultErrback);
}
else {
var result = {};
result.affected_rows = this.affected_rows = this.protocol.affected_rows;
result.insert_id = this.insert_id = this.protocol.insert_id;
result.server_status = this.server_status = this.protocol.server_status;
result.warning_count = this.warning_count = this.protocol.warning_count;
result.info = this.info = this.protocol.message;
try {
if(callback) callback(result);
}
catch(error) {
(errback || this.defaultErrback)(error);
}
}
}))
.addErrback(errback || this.defaultErrback);
}
Connection.prototype.extract_placeholder = function(sql) {
if(typeof(sql)=='string') return sql;
var format = sql[0];
var bind = sql.slice(1).map(function(v) {
return types.convertToSQLString(v);
});
if(format.match(/\?/g).length!=bind.length) {
return new errors.ClientError('parameter count mismatch');
}
return format.replace(/\?/g, function() {
return bind.shift();
});
}
Connection.prototype.set_server_option = function(opt) {
return this.protocol.set_option_command(opt);
}
Connection.prototype.get_result = function(fields) {
var res = new result.Result(this.fields.map(function(field) {
return(new Field(field));
}), this.protocol);
return res.fetch_all();
}
Connection.prototype.has_more_results = function() {
return !!(this.protocol.server_status & constants.server.MORE_RESULTS_EXISTS);
}
Connection.prototype.next_result = function(callback, errback) {
if(!this.has_more_results()) {
process.nextTick(new Error("ClientError", "Don't have more results"));
return;
}
this.protocol.get_result()
.addCallback(utils.scope(this, function(nfields) {
this.protocol.retr_fields(nfields)
.addCallback(utils.scope(this, function(fields) {
this.fields = fields;
this.result_exist = true;
this.get_result()
.addCallback(utils.scope(this, function(results) {
try {
if(callback) callback(results);
}
catch(error) {
(errback || this.defaultErrback)(error);
}
}))
.addErrback(errback || this.defaultErrback);
}))
.addErrback(errback || this.defaultErrback);
}))
.addErrback(errback || this.defaultErrback);
}
Connection.prototype.prepare = function(str, callback, errback) {
var stmt = new Stmt(this.protocol, this.charset);
return stmt.prepare(str, callback, (errback || this.defaultErrback));
};
var Stmt = function(protocol, charset) {
this.protocol = protocol;
this.charset = charset;
this.statement_id = undefined;
this.affected_rows = this.insert_id = this.server_status = this.warning_count = 0;
this.sqlstate = "00000";
this.param_count = undefined;
}
Stmt.prototype.close = function() {
this.protocol.stmt_close_command(this.statement_id);
this.statement_id = undefined;
this.param_count = undefined;
}
Stmt.prototype.prepare = function(query, callback, errback) {
this.close();
this.protocol.stmt_prepare_command(query)
.addCallback(utils.scope(this, function(statement_id, param_count, field_packets) {
this.statement_id = statement_id;
this.sqlstate = "00000";
this.param_count = param_count;
this.fields = field_packets.map(function(field_packet) {
return new Field(field_packet);
});
try {
if(callback) callback(this);
}
catch(error) {
(errback || this.defaultErrback)(error);
}
}))
.addErrback(errback || this.defaultErrback);
}
Stmt.prototype.execute = function(args, callback, errback) {
if(typeof(this.param_count)=='undefined') {
errback(new errors.ClientError("not prepared"));
return;
}
if(this.param_count!=args.length) {
errback(new errors.ClientError("parameter count mismatch"));
return;
}
this.sqlstate = "00000";
this.protocol.stmt_execute_command(this.statement_id, args)
.addCallback(utils.scope(this, function(nfields) {
if(typeof(nfields)!='undefined') {
this.protocol.retr_fields(nfields)
.addCallback(utils.scope(this, function(fields) {
this.fields = fields;
this.result = new result.StatementResult(this.fields, this.protocol);
this.protocol.stmt_retr_all_records(fields, this.charset)
.addCallback(utils.scope(this, function(records) {
this.result.records = records;
try {
callback(this.result);
}
catch(error) {
(errback || this.defaultErrback)(error);
}
}))
.addErrback(errback || this.defaultErrback);
}))
.addErrback(errback || this.defaultErrback);
}
else {
this.affected_rows = this.protocol.affected_rows;
this.insert_id = this.protocol.insert_id;
this.server_status = this.protocol.server_status;
this.warning_count = this.protocol.warning_count;
this.info = this.protocol.message;
try {
callback();
}
catch(error) {
(errback || this.defaultErrback)(error);
}
}
}))
.addErrback(errback || this.defaultErrback);
}
var Field = function(packet) {
this.db = packet.db;
this.table = packet.table;
this.org_table = packet.org_table;
this.name = packet.name;
this.org_name = packet.org_name;
this.charsetnr = packet.charsetnr;
this.length = packet.length;
this.type = packet.type;
this.flags = packet.flags;
this.decimals = packet.decimals;
this.defaultVal = packet.defaultVal;
}
exports.Field = Field;
Field.prototype.is_num = function() {
return [constants.field.TYPE_DECIMAL, constants.field.TYPE_TINY, constants.field.TYPE_SHORT, constants.field.TYPE_LONG, constants.field.TYPE_FLOAT, constants.field.TYPE_DOUBLE, constants.field.TYPE_LONGLONG, constants.field.TYPE_INT24].indexOf(this.type.id) >= 0;
}
Field.prototype.is_not_null = function() {
return !!(this.flags & constants.field.NOT_NULL_FLAG);
}
Field.prototype.is_pri_key = function() {
return !!(this.flags & constants.field.PRI_KEY_FLAG);
}
/*
node-mysql
A node.js interface for MySQL
Author: masuidrive <masui@masuidrive.jp>
License: MIT License
Copyright (c) Yuichiro MASUI
# Original:
# http://github.com/tmtm/ruby-mysql
# Copyright (C) 2009-2010 TOMITA Masahiro
# mailto:tommy@tmtm.org
# License: Ruby's
*/
var sha1;
try {
var crypto = require('crypto');
sha1 = function(message) {
return (new crypto.Hash).init("sha1").update(message).digest();
}
}
catch(e) {
var SHA1 = require('./sha1').SHA1;
var i32tostr = function(i32) {
var ret = '';
for (var i=0; i<4; ++i) {
v = i32 & 0xff;
i32 >>>= 8;
ret = String.fromCharCode(v) + ret;
}
return ret;
};
sha1 = function(message) {
var digest = new SHA1(message).digest();
var ret = "";
for(var i=0; i<digest.length; ++i) {
ret += i32tostr(digest[i]);
}
return ret;
}
}
exports.encrypt_password = function(plain, scramble) {
var stage1 = sha1(plain);
var stage2 = sha1(scramble+sha1(stage1));
var result = "";
for(var i=0; i<stage1.length; ++i) {
result += String.fromCharCode(stage1.charCodeAt(i) ^ stage2.charCodeAt(i));
}
return(result);
}
/*
node-mysql
A node.js interface for MySQL
http://github.com/masuidrive/node-mysql
Copyright (c) Yuichiro MASUI <masui@masuidrive.jp>
License: MIT License
*/
// RawConnection:
// MySQL packet I/O
// http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#The_Packet_Header
var sys = require('sys');
var events = require("events");
var pack = require('./pack');
var utils = require('./utils');
var errors = require('./errors');
var Promise = require('./node-promise').Promise;
var Socket = require('./node-socket').Socket;
var MAX_PACKET_LENGTH = 16777215;
var Connection = function(port, hostname) {
events.EventEmitter.call(this);
this.hostname = hostname;
this.port = port;
this.seq = 0; // packet sequence number
this.socket = new Socket(utils.scope(this, function(){ this.emit("connect"); }),
utils.scope(this, function(){ this.emit("close"); }));
}
sys.inherits(Connection, events.EventEmitter);
exports.Connection = Connection;
// set timeout
Connection.prototype.timeout = function(timeout) {
this.socket.timeout(timeout);
}
// open TCP socket
Connection.prototype.connect = function() {
this.socket.connect(this.port, this.hostname);
}
// reset packet sequence
Connection.prototype.reset = function() {
this.seq = 0;
}
// close TCP socket
Connection.prototype.close = function() {
this.socket.close();
}
// Either "closed", "open", "opening", "readOnly", or "writeOnly".
Connection.prototype.readyState = function() {
return this.socket.readyState();
}
// Read one packet data
Connection.prototype.read = function(packet_count) {
var promise = new Promise();
var ret = "";
var len = undefined;
var packets = [];
var read_packet = utils.scope(this, function() {
try {
this.socket.read(4)
.addCallback(utils.scope(this, function(header) {
try {
var res = pack.unpack("CvC", header);
len = (res[1] << 8) + res[0];
if(res[2] != this.seq) {
promise.emitError(new errors.ProtocolError("invalid packet: sequence number mismatch("+res[2]+" != "+this.seq+"(expected))"));
return;
}
this.seq = (res[2] + 1) % 256;
this.socket.read(len)
.addCallback(utils.scope(this, function(data) {
try {
ret = ret.concat(data);
var sqlstate = "00000";
// Error packet
if(ret[0]=="\xff") {
var res = pack.unpack("Cvaa5a*", ret);
var f = res[0], errno = res[1], marker = res[2], sqlstate = res[3], message = res[4];
if(marker!="#") {
res = pack.unpack("Cva*", ret); // Version 4.0 Error
f = res[0], errno = res[1], message = res[2];
sqlstate = "";
}
promise.emitError(new errors.ServerError(message, errno, sqlstate));
}
else {
packets.push(ret);
if(typeof(packet_count)=='undefined') {
promise.emitSuccess(ret);
}
else if(packets.length>=packet_count) {
promise.emitSuccess(packets);
}
else {
read_packet();
}
}
}
catch(e) {
promise.emitError(new errors.ClientError(String(e)));
}
}))
.addErrback(utils.scope(this, function(error) {
promise.emitError(error);
}));
}
catch(e) {
promise.emitError(new errors.ClientError(String(e)));
}
}))
.addErrback(utils.scope(this, function(error) {
promise.emitError(error);
}));
}
catch(e) {
promise.emitError(new errors.ClientError(String(e)));
}
});
read_packet();
return promise;
}
// Write one packet data
Connection.prototype.write = function(data) {
try {
var promise = new Promise();
if(typeof(data)=='undefined') {
this.socket.write(pack.pack("CvC", 0, 0, this.seq));
this.seq = (this.seq + 1) % 256
promise.emitSuccess();
}
else {
var buf;
while(data) {
buf = data.substring(0, MAX_PACKET_LENGTH);
data = data.slice(MAX_PACKET_LENGTH);
this.socket.write(pack.pack("CvC", buf.length%256, buf.length/256, this.seq));
this.socket.write(buf);
this.seq = (this.seq + 1) % 256;
}
promise.emitSuccess();
}
}
catch(e) {
promise.emitError(new errors.ClientError(String(e)));
}
return promise;
}
/*
node-mysql
A node.js interface for MySQL
Author: masuidrive <masui@masuidrive.jp>
License: MIT License
Copyright (c) Yuichiro MASUI
# Original:
# http://github.com/tmtm/ruby-mysql
# Copyright (C) 2009-2010 TOMITA Masahiro
# mailto:tommy@tmtm.org
# License: Ruby's
*/
exports.com = {
SLEEP : 0,
QUIT : 1,
INIT_DB : 2,
QUERY : 3,
FIELD_LIST : 4,
CREATE_DB : 5,
DROP_DB : 6,
REFRESH : 7,
SHUTDOWN : 8,
STATISTICS : 9,
PROCESS_INFO : 10,
CONNECT : 11,
PROCESS_KILL : 12,
DEBUG : 13,
PING : 14,
TIME : 15,
DELAYED_INSERT : 16,
CHANGE_USER : 17,
BINLOG_DUMP : 18,
TABLE_DUMP : 19,
CONNECT_OUT : 20,
REGISTER_SLAVE : 21,
STMT_PREPARE : 22,
STMT_EXECUTE : 23,
STMT_SEND_LONG_DATA : 24,
STMT_CLOSE : 25,
STMT_RESET : 26,
SET_OPTION : 27,
STMT_FETCH : 28
};
// Client flag
exports.client = {
LONG_PASSWORD : 1, // new more secure passwords
FOUND_ROWS : 1 << 1, // Found instead of affected rows
LONG_FLAG : 1 << 2, // Get all column flags
CONNECT_WITH_DB : 1 << 3, // One can specify db on connect
NO_SCHEMA : 1 << 4, // Don't allow database.table.column
COMPRESS : 1 << 5, // Can use compression protocol
ODBC : 1 << 6, // Odbc client
LOCAL_FILES : 1 << 7, // Can use LOAD DATA LOCAL
IGNORE_SPACE : 1 << 8, // Ignore spaces before '('
PROTOCOL_41 : 1 << 9, // New 4.1 protocol
INTERACTIVE : 1 << 10, // This is an interactive client
SSL : 1 << 11, // Switch to SSL after handshake
IGNORE_SIGPIPE : 1 << 12, // IGNORE sigpipes
TRANSACTIONS : 1 << 13, // Client knows about transactions
RESERVED : 1 << 14, // Old flag for 4.1 protocol
SECURE_CONNECTION : 1 << 15, // New 4.1 authentication
MULTI_STATEMENTS : 1 << 16, // Enable/disable multi-stmt support
MULTI_RESULTS : 1 << 17 // Enable/disable multi-results
};
// Connection Option
exports.option = {
OPT_CONNECT_TIMEOUT : 0,
OPT_COMPRESS : 1,
OPT_NAMED_PIPE : 2,
INIT_COMMAND : 3,
READ_DEFAULT_FILE : 4,
READ_DEFAULT_GROUP : 5,
SET_CHARSET_DIR : 6,
SET_CHARSET_NAME : 7,
OPT_LOCAL_INFILE : 8,
OPT_PROTOCOL : 9,
SHARED_MEMORY_BASE_NAME : 10,
OPT_READ_TIMEOUT : 11,
OPT_WRITE_TIMEOUT : 12,
OPT_USE_RESULT : 13,
OPT_USE_REMOTE_CONNECTION : 14,
OPT_USE_EMBEDDED_CONNECTION : 15,
OPT_GUESS_CONNECTION : 16,
SET_CLIENT_IP : 17,
SECURE_AUTH : 18,
REPORT_DATA_TRUNCATION : 19,
OPT_RECONNECT : 20,
OPT_SSL_VERIFY_SERVER_CERT : 21,
// Server Option,
MULTI_STATEMENTS_ON : 0,
MULTI_STATEMENTS_OFF : 1
};
// Server Status
exports.server = {
STATUS_IN_TRANS : 1,
STATUS_AUTOCOMMIT : 1 << 1,
MORE_RESULTS_EXISTS : 1 << 3,
QUERY_NO_GOOD_INDEX_USED : 1 << 4,
QUERY_NO_INDEX_USED : 1 << 5,
STATUS_CURSOR_EXISTS : 1 << 6,
STATUS_LAST_ROW_SENT : 1 << 7,
STATUS_DB_DROPPED : 1 << 8,
STATUS_NO_BACKSLASH_ESCAPES : 1 << 9
};
// Refresh parameter
exports.refresh = {
GRANT : 1,
LOG : 1 << 1,
TABLES : 1 << 2,
HOSTS : 1 << 3,
STATUS : 1 << 4,
THREADS : 1 << 5,
SLAVE : 1 << 6,
MASTER : 1 << 7,
READ_LOCK : 1 << 14,
FAST : 1 << 15
};
exports.field = {
// Field type
TYPE_DECIMAL : 0,
TYPE_TINY : 1,
TYPE_SHORT : 2,
TYPE_LONG : 3,
TYPE_FLOAT : 4,
TYPE_DOUBLE : 5,
TYPE_NULL : 6,
TYPE_TIMESTAMP : 7,
TYPE_LONGLONG : 8,
TYPE_INT24 : 9,
TYPE_DATE : 10,
TYPE_TIME : 11,
TYPE_DATETIME : 12,
TYPE_YEAR : 13,
TYPE_NEWDATE : 14,
TYPE_VARCHAR : 15,
TYPE_BIT : 16,
TYPE_NEWDECIMAL : 246,
TYPE_ENUM : 247,
TYPE_SET : 248,
TYPE_TINY_BLOB : 249,
TYPE_MEDIUM_BLOB : 250,
TYPE_LONG_BLOB : 251,
TYPE_BLOB : 252,
TYPE_VAR_STRING : 253,
TYPE_STRING : 254,
TYPE_GEOMETRY : 255,
TYPE_CHAR : 1, // TYPE_TINY
TYPE_INTERVAL : 247, // TYPE_ENUM
// Flag
NOT_NULL_FLAG : 1,
PRI_KEY_FLAG : 1 << 1,
UNIQUE_KEY_FLAG : 1 << 2,
MULTIPLE_KEY_FLAG : 1 << 3,
BLOB_FLAG : 1 << 4,
UNSIGNED_FLAG : 1 << 5,
ZEROFILL_FLAG : 1 << 6,
BINARY_FLAG : 1 << 7,
ENUM_FLAG : 1 << 8,
AUTO_INCREMENT_FLAG : 1 << 9,
TIMESTAMP_FLAG : 1 << 10,
SET_FLAG : 1 << 11,
PART_KEY_FLAG : 1 << 14,
NUM_FLAG : 1 << 15,
GROUP_FLAG : 1 << 15,
UNIQUE_FLAG : 1 << 16,
BINCMP_FLAG : 1 << 17,
};
exports.stmt = {
// Cursor type
CURSOR_TYPE_NO_CURSOR : 0,
CURSOR_TYPE_READ_ONLY : 1
};
/*
node-mysql
A node.js interface for MySQL
Author: masuidrive <masui@masuidrive.jp>
License: MIT License
Copyright (c) Yuichiro MASUI
# Original:
# http://github.com/tmtm/ruby-mysql
# Copyright (C) 2009-2010 TOMITA Masahiro
# mailto:tommy@tmtm.org
# License: Ruby's
*/
// Promise library
// compatible with < 0.1.30
// It was changed for
// Original:
// nodejs v0.1.29
// Copyright 2009, 2010 Ryan Lienhart Dahl. All rights reserved.
// MIT License
var sys = require('sys');
var events = require('events');
exports.Promise = function () {
events.EventEmitter.call(this);
this._blocking = false;
this.hasFired = false;
this._values = undefined;
};
sys.inherits(exports.Promise, events.EventEmitter);
exports.Promise.prototype.timeout = function(timeout, createError) {
if (!timeout) {
return this._timeoutDuration;
}
this._timeoutDuration = timeout;
if (this.hasFired) return;
this._clearTimeout();
var self = this;
this._timer = setTimeout(function() {
self._timer = null;
if (self.hasFired) {
return;
}
self.emitError(createError ? createError() : new Error('timeout'));
}, timeout/100);
return this;
};
exports.Promise.prototype._clearTimeout = function() {
if (!this._timer) return;
clearTimeout(this._timer);
this._timer = null;
}
exports.Promise.prototype.emitSuccess = function() {
if (this.hasFired) return;
this.hasFired = 'success';
this._clearTimeout();
this._values = Array.prototype.slice.call(arguments);
this.emit.apply(this, ['success'].concat(this._values));
};
exports.Promise.prototype.emitError = function() {
if (this.hasFired) return;
this.hasFired = 'error';
this._clearTimeout();
this._values = Array.prototype.slice.call(arguments);
this.emit.apply(this, ['error'].concat(this._values));
if (this.listeners('error').length == 0) {
var self = this;
process.nextTick(function() {
if (self.listeners('error').length == 0) {
throw (self._values[0] instanceof Error)
? self._values[0]
: new Error('Unhandled emitError: '+JSON.stringify(self._values));
}
});
}
};
exports.Promise.prototype.addCallback = function (listener) {
if(typeof(listener)=='undefined') return this;;
if (this.hasFired === 'success') {
listener.apply(this, this._values);
}
return this.addListener("success", listener);
};
exports.Promise.prototype.addErrback = function (listener) {
if(typeof(listener)=='undefined') return this;
if (this.hasFired === 'error') {
listener.apply(this, this._values);
}
return this.addListener("error", listener);
};
/* Poor Man's coroutines */
var coroutineStack = [];
exports.Promise.prototype._destack = function () {
this._blocking = false;
while (coroutineStack.length > 0 &&
!coroutineStack[coroutineStack.length-1]._blocking)
{
coroutineStack.pop();
process.unloop("one");
}
};
//
// Append read() to tcp.Connection
//
var sys = require('sys');
var tcp = require("net");
var events = require("events");
var errors = require('./errors');
var utils = require('./utils');
var Promise = require('./node-promise').Promise;
var Socket = function(connect_callback, close_callback) {
this.conn = undefined;
this._timeout = 0;
this.buffer = '';
this.read_queue = [];
this.connect_callback = connect_callback;
this.close_callback = close_callback;
}
sys.inherits(Socket, events.EventEmitter);
exports.Socket = Socket;
Socket.prototype.timeout = function(timeout) {
this._timeout = timeout;
}
Socket.prototype.connect = function(port, host) {
if(this.conn) {
throw "Already open";
}
else {
this.conn = tcp.createConnection(port, host);
this.conn.addListener("data", utils.scope(this, function(data) {
this.buffer += data;
this.process_tcp_read_queue();
}));
this.conn.addListener("connect", utils.scope(this, function(){
this.conn.setEncoding("binary");
this.conn.setNoDelay(true);
this.conn.setTimeout(this._timeout);
this.connect_callback();
}));
this.conn.addListener("close", utils.scope(this, function(hasError) {
var task;
while(task=this.read_queue.shift()) {
task.promise.emitError(new errors.ClientError('connection was closed'));
}
this.conn = undefined;
this.close_callback(hasError);
}));
}
}
Socket.prototype.readyState = function() {
return this.conn.readyState;
}
Socket.prototype.close = function() {
if(this.conn) this.conn.end();
}
Socket.prototype.read = function(len) {
var promise = new Promise();
if(this._timeout) promise.timeout(this._timeout, function(){ return new errors.ClientError('connection timeout'); });
this.read_queue.push({len: len, promise: promise});
if(this.buffer) this.process_tcp_read_queue();
return promise;
}
Socket.prototype.process_tcp_read_queue = function() {
if(this.read_queue.length==0) return;
var task, data;
if(typeof(this.read_queue[0].len)=='undefined') {
task = this.read_queue.shift();
data = this.buffer;
this.buffer = '';
task.promise.emitSuccess(data);
}
else if(this.buffer.length>=this.read_queue[0].len) {
task = this.read_queue.shift();
data = this.buffer.substring(0, task.len);
this.buffer = this.buffer.slice(task.len);
task.promise.emitSuccess(data);
this.process_tcp_read_queue();
}
}
Socket.prototype.write = function(data) {
this.conn.write(data, 'binary');
}
/*
node-mysql
A node.js interface for MySQL
Author: masuidrive <masui@masuidrive.jp>
License: MIT License
Copyright (c) Yuichiro MASUI
*/
// Result:
// Result set
var sys = require('sys');
var utils = require('./utils');
// Result set
var ResultBase = function(fields) {
this.fields = fields;
this.records = [];
this.fieldname_with_table = false;
}
exports.ResultBase = ResultBase;
var Result = function(fields, protocol) {
ResultBase.call(this, fields);
this.protocol = protocol;
}
sys.inherits(Result, ResultBase);
exports.Result = Result;
Result.prototype.fetch_all = function() {
var promise = this.protocol.retr_all_records(this.fields,
utils.scope(this, function(rec) { // each
this.records.push(rec);
}),
utils.scope(this, function() { // result
return this;
}));
return promise;
}
Result.prototype.toHash = function(row) {
var result, name, field;
result = {};
for(var i = 0; i<this.fields.length; ++i) {
field = this.fields[i];
name = ((this.fieldname_with_table && field.table) ? (field.table+".") : "") + field.name;
result[name] = row[i];
}
return result;
}
var StatementResult = function(fields, protocol) {
ResultBase.call(this, fields);
this.protocol = protocol;
}
sys.inherits(StatementResult, ResultBase);
exports.StatementResult = Result;
/*
node-mysql
A node.js interface for MySQL
Author: masuidrive <masui@masuidrive.jp>
License: MIT License
Copyright (c) Yuichiro MASUI
# Original:
# http://github.com/tmtm/ruby-mysql
# Copyright (C) 2009-2010 TOMITA Masahiro
# mailto:tommy@tmtm.org
# License: Ruby's
*/
var constants = require('./constants');
var Time = function(year, month, day, hour, minute, second, neg, second_part) {
this.year = year || 0;
this.month = month || 0;
this.day = day || 0;
this.hour = hour || 0;
this.minute = minute || 0;
this.second = second || 0;
this.neg = !!neg;
this.second_part = second_part;
return this;
}
exports.Time = Time;
Time.prototype.toString = function() {
var date = [this.year, this.month, this.day].join("-");
var time = [this.hour, this.minute, this.second].join(":");
if(date=='0-0-0') return time;
return [date, time].join(' ');
}
Time.prototype.equals = function(obj) {
return this.year == obj.year && this.month == obj.month && this.day == obj.day && this.hour == obj.hour && this.minute == obj.minute && this.second == obj.second;
}
var convertToSQLString = function(val) {
switch(typeof(val)) {
case 'undefined':
return 'NULL';
case 'string':
return "'"+quote(val)+"'"
case 'boolean':
return val?'true':'false';
case 'number':
return String(val);
}
if(val.join) { // if array
return convertToSQLString(val.join(','));
}
return "'"+quote(String(val))+"'";
}
exports.convertToSQLString = convertToSQLString;
var quote = function(str) {
return str.replace(/[\0\n\r\\\'\"\x1a]/g, function(s) {
switch(s) {
case "\0":
return "\\0";
case "\n":
return "\\n";
case "\r":
return "\\r";
case "\x1a":
return "\\Z";
default:
return "\\"+s;
}
});
}
exports.quote = quote;
var parseTime = function(val) {
var part = val.match(/^(0*(\d+) |)0*(\d+):0*(\d+):+0*(\d+)/);
if(part) {
part = part.map(function(s) {
return typeof(s)=='undefined' ? 0 : parseInt(s);
});
return new Time(0, 0, part[2], part[3], part[4], part[5]);
}
var part = val.match(/^(0*(\d+)-0*(\d+)-|)0*(\d+) *(0*(\d+):0*(\d+):+0*(\d+)|)/);
if(part) {
part = part.map(function(s) {
return typeof(s)=='undefined' ? 0 : parseInt(s);
});
return new Time(part[2], part[3], part[4], part[6], part[7], part[8]);
}
return undefined;
}
var Types = {};
Types[constants.field.TYPE_DECIMAL] = {
id: constants.field.TYPE_DECIMAL,
name: 'DECIMAL',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseFloat(val);
}
};
Types[constants.field.TYPE_TINY] = {
id: constants.field.TYPE_TINY,
name: 'TINY',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseInt(val);
}
};
Types[constants.field.TYPE_SHORT] = {
id: constants.field.TYPE_SHORT,
name: 'SHORT',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseInt(val);
}
};
Types[constants.field.TYPE_LONG] = {
id: constants.field.TYPE_LONG,
name: 'LONG',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseInt(val);
}
};
Types[constants.field.TYPE_FLOAT] = {
id: constants.field.TYPE_FLOAT,
name: 'FLOAT',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseFloat(val);
}
};
Types[constants.field.TYPE_DOUBLE] = {
id: constants.field.TYPE_DOUBLE,
name: 'DOUBLE',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseFloat(val);
}
};
Types[constants.field.TYPE_NULL] = {
id: constants.field.TYPE_NULL,
name: 'NULL',
convert: function(val, charset, field) {
return null;
}
};
Types[constants.field.TYPE_TIMESTAMP] = {
id: constants.field.TYPE_TIMESTAMP,
name: 'TIMESTAMP',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseTime(val);
}
};
Types[constants.field.TYPE_LONGLONG] = {
id: constants.field.TYPE_LONGLONG,
name: 'LONGLONG',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseInt(val);
}
};
Types[constants.field.TYPE_INT24] = {
id: constants.field.TYPE_INT24,
name: 'INT24',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseInt(val);
}
};
Types[constants.field.TYPE_DATE] = {
id: constants.field.TYPE_DATE,
name: 'DATE',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseTime(val);
}
};
Types[constants.field.TYPE_TIME] = {
id: constants.field.TYPE_TIME,
name: 'TIME',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseTime(val);
}
};
Types[constants.field.TYPE_DATETIME] = {
id: constants.field.TYPE_DATETIME,
name: 'DATETIME',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseTime(val);
}
};
Types[constants.field.TYPE_YEAR] = {
id: constants.field.TYPE_YEAR,
name: 'YEAR',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseInt(val);
}
};
Types[constants.field.TYPE_NEWDATE] = {
id: constants.field.TYPE_NEWDATE,
name: 'NEWDATE',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseTime(val);
}
};
Types[constants.field.TYPE_VARCHAR] = {
id: constants.field.TYPE_VARCHAR,
name: 'VARCHAR',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : charset.convertFromBytes(val);
}
};
Types[constants.field.TYPE_BIT] = {
id: constants.field.TYPE_BIT,
name: 'BIT',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : val;
}
};
Types[constants.field.TYPE_NEWDECIMAL] = {
id: constants.field.TYPE_NEWDECIMAL,
name: 'NEWDECIMAL',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : parseFloat(val);
}
};
Types[constants.field.TYPE_ENUM] = {
id: constants.field.TYPE_ENUM,
name: 'ENUM',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : charset.convertFromBytes(val);
}
};
Types[constants.field.TYPE_SET] = {
id: constants.field.TYPE_SET,
name: 'SET',
convert: function(val, charset, field) {
if(typeof(val)=='undefined') return undefined;
return val=='' ? [] : charset.convertFromBytes(val.split(','));
}
};
Types[constants.field.TYPE_TINY_BLOB] = {
id: constants.field.TYPE_TINY_BLOB,
name: 'TINY_BLOB',
convert: function(val, charset, field) {
if(field.flags & constants.field.BINARY_FLAG) return val;
return typeof(val)=='undefined' ? null : charset.convertFromBytes(val);
}
};
Types[constants.field.TYPE_MEDIUM_BLOB] = {
id: constants.field.TYPE_MEDIUM_BLOB,
name: 'MEDIUM_BLOB',
convert: function(val, charset, field) {
if(field.flags & constants.field.BINARY_FLAG) return val;
return typeof(val)=='undefined' ? null : charset.convertFromBytes(val);
}
};
Types[constants.field.TYPE_LONG_BLOB] = {
id: constants.field.TYPE_LONG_BLOB,
name: 'LONG_BLOB',
convert: function(val, charset, field) {
if(field.flags & constants.field.BINARY_FLAG) return val;
return typeof(val)=='undefined' ? null : charset.convertFromBytes(val);
}
};
Types[constants.field.TYPE_BLOB] = {
id: constants.field.TYPE_BLOB,
name: 'BLOB',
convert: function(val, charset, field) {
if(field.flags & constants.field.BINARY_FLAG) return val;
return typeof(val)=='undefined' ? null : charset.convertFromBytes(val);
}
};
Types[constants.field.TYPE_VAR_STRING] = {
id: constants.field.TYPE_VAR_STRING,
name: 'VAR_STRING',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : charset.convertFromBytes(val);
}
};
Types[constants.field.TYPE_STRING] = {
id: constants.field.TYPE_STRING,
name: 'STRING',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : charset.convertFromBytes(val);
}
};
Types[constants.field.TYPE_GEOMETRY] = {
id: constants.field.TYPE_GEOMETRY,
name: 'GEOMETRY',
convert: function(val, charset, field) {
return typeof(val)=='undefined' ? null : val;
}
};
exports.Types = Types;
\ No newline at end of file
var scope = function(target, func) {
return function(){ return func.apply(target, arguments); }
}
exports.scope = scope;
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!