瀏覽代碼

[cpp] Some initial support for mysql/sqlite. Not very well tested yet.

Hugh 11 年之前
父節點
當前提交
aa48ddc369
共有 3 個文件被更改,包括 391 次插入0 次删除
  1. 3 0
      std/cpp/_std/Date.hx
  2. 202 0
      std/cpp/_std/sys/db/Mysql.hx
  3. 186 0
      std/cpp/_std/sys/db/Sqlite.hx

+ 3 - 0
std/cpp/_std/Date.hx

@@ -50,6 +50,9 @@
 	public static function now() : Date {
 		return fromTime( untyped __global__.__hxcpp_date_now()*1000.0);
 	}
+  	private static function new1(t : Dynamic) : Date {
+		return  new Date(2005,1,1,0,0,0);
+	}
 
 	public static function fromTime( t : Float ) : Date {
 		var result = new Date(0,0,0,0,0,0);

+ 202 - 0
std/cpp/_std/sys/db/Mysql.hx

@@ -0,0 +1,202 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package sys.db;
+
+private class D {
+
+	static function load(fun,args) : Dynamic {
+		return cpp.Lib.load(lib,fun,args);
+	}
+
+	static var lib = "mysql5";
+	public static var connect = load("mysql_connect",1);
+	public static var select_db = load("select_db",2);
+	public static var request = load("request",2);
+	public static var close = load("close",1);
+	public static var escape = load("escape", 2);
+	public static var set_conv_funs = load("set_conv_funs", 4);
+	public static var result_get_length = load("result_get_length",1);
+	public static var result_get_nfields = load("result_get_nfields",1);
+	public static var result_next = load("result_next",1);
+	public static var result_get = load("result_get",2);
+	public static var result_get_int = load("result_get_int",2);
+	public static var result_get_float = load("result_get_float",2);
+	public static var result_fields_names = cpp.Lib.loadLazy(lib,"result_get_fields_names",1);
+
+}
+
+private class MysqlResultSet implements sys.db.ResultSet {
+
+	public var length(get,null) : Int;
+	public var nfields(get,null) : Int;
+	private var __r : Dynamic;
+	private var cache : Dynamic;
+
+	public function new(r) {
+		__r = r;
+	}
+
+	private function get_length() {
+		return D.result_get_length(__r);
+	}
+
+	private function get_nfields() {
+		return D.result_get_nfields(__r);
+	}
+
+	public function hasNext() {
+		if( cache == null )
+			cache = next();
+		return (cache != null);
+	}
+
+	public function next() : Dynamic {
+		var c = cache;
+		if( c != null ) {
+			cache = null;
+			return c;
+		}
+		c = D.result_next(__r);
+		return c;
+	}
+
+	public function results() : List<Dynamic> {
+		var l = new List();
+		while( hasNext() )
+			l.add(next());
+		return l;
+	}
+
+	public function getResult( n : Int ) {
+		return new String(D.result_get(__r,n));
+	}
+
+	public function getIntResult( n : Int ) : Int {
+		return D.result_get_int(__r,n);
+	}
+
+	public function getFloatResult( n : Int ) : Float {
+		return D.result_get_float(__r,n);
+	}
+
+	public function getFieldsNames() : Array<String> {
+		var a = D.result_fields_names(__r);
+		return a;
+	}
+
+}
+
+private class MysqlConnection implements sys.db.Connection {
+
+	private var __c : Dynamic;
+
+	public function new(c) {
+		__c = c;
+		D.set_conv_funs(c, function(s) return new String(s), function(d) return untyped Date.new1(d), function(b) return haxe.io.Bytes.ofData(b));
+	}
+
+	public function request( s : String ) : sys.db.ResultSet {
+			var r = D.request(this.__c, s);
+			return new MysqlResultSet(r);
+	}
+
+	public function close() {
+		D.close(__c);
+	}
+
+	public function escape( s : String ) {
+		return new String(D.escape(__c,s));
+	}
+
+	public function quote( s : String ) {
+		return "'"+escape(s)+"'";
+	}
+
+	public function addValue( s : StringBuf, v : Dynamic ) {
+		if (v == null) {
+			s.add(v);
+      }
+      else {
+			var t:Int = untyped v.__GetType();
+			if( t == 0xff )
+				s.add(v);
+			else if( t == 2 )
+				s.add( untyped v.__GetInt() ? "1".code : "0".code );
+			else {
+				s.addChar("'".code);
+				s.add(escape(Std.string(v)));
+				s.addChar("'".code);
+			}
+		}
+	}
+
+	public function lastInsertId() {
+		return request("SELECT LAST_INSERT_ID()").getIntResult(0);
+	}
+
+	public function dbName() {
+		return "MySQL";
+	}
+
+	public function startTransaction() {
+		request("START TRANSACTION");
+	}
+
+	public function commit() {
+		request("COMMIT");
+	}
+
+	public function rollback() {
+		request("ROLLBACK");
+	}
+
+	private static var __use_date = Date;
+}
+
+@:coreApi class Mysql {
+
+	public static function connect( params : {
+		host : String,
+		?port : Int,
+		user : String,
+		pass : String,
+		?socket : String,
+		database : String
+	} ) : sys.db.Connection {
+		var o = {
+			host : params.host,
+			port : if( params.port == null ) 3306 else params.port,
+			user : params.user,
+			pass : params.pass,
+			socket : if( params.socket == null ) null else params.socket
+		};
+		var c = D.connect(o);
+		try {
+			D.select_db(c,params.database);
+		} catch( e : Dynamic ) {
+			D.close(c);
+			cpp.Lib.rethrow(e);
+		}
+		return new MysqlConnection(c);
+	}
+
+}

+ 186 - 0
std/cpp/_std/sys/db/Sqlite.hx

@@ -0,0 +1,186 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package sys.db;
+
+private class SqliteConnection implements Connection {
+
+	var c : Dynamic;
+
+	public function new( file : String ) {
+		c = _connect(file);
+	}
+
+	public function close() {
+		_close(c);
+	}
+
+	public function request( s : String ) : ResultSet {
+		try {
+			return new SqliteResultSet(_request(c,s));
+		} catch( e : String ) {
+			throw "Error while executing "+s+" ("+e+")";
+		}
+	}
+
+	public function escape( s : String ) {
+		return s.split("'").join("''");
+	}
+
+	public function quote( s : String ) {
+		if( s.indexOf("\000") >= 0 )
+			return "x'"+new String(_encode(s,"0123456789ABCDEF"))+"'";
+		return "'"+s.split("'").join("''")+"'";
+	}
+
+	public function addValue( s : StringBuf, v : Dynamic ) {
+		if (v == null) {
+			s.add(v);
+      }
+      else {
+			var t:Int = untyped v.__GetType();
+			if( t == 0xff )
+				s.add(v);
+			else if( t == 2 )
+				s.add( untyped v.__GetInt() );
+			else
+				s.add(quote(Std.string(v)));
+		}
+	}
+
+	public function lastInsertId() {
+		return _last_id(c);
+	}
+
+	public function dbName() {
+		return "SQLite";
+	}
+
+	public function startTransaction() {
+		request("BEGIN TRANSACTION");
+	}
+
+	public function commit() {
+		request("COMMIT");
+		startTransaction(); // match mysql usage
+	}
+
+	public function rollback() {
+		request("ROLLBACK");
+		startTransaction(); // match mysql usage
+	}
+
+	static var _encode = cpp.Lib.load("std","base_encode",2);
+	static var _connect = cpp.Lib.load("sqlite","sqlite_connect",1);
+	static var _close = cpp.Lib.load("sqlite","close",1);
+	static var _request = cpp.Lib.load("sqlite","request",2);
+	static var _last_id = cpp.Lib.load("sqlite","last_insert_id",1);
+}
+
+
+private class SqliteResultSet implements ResultSet {
+
+	public var length(get,null) : Int;
+	public var nfields(get,null) : Int;
+	var r : Dynamic;
+	var cache : List<Dynamic>;
+
+	public function new( r ) {
+		cache = new List();
+		this.r = r;
+		hasNext(); // execute the request
+	}
+
+	function get_length() {
+		if( nfields != 0 ) {
+			while( true ) {
+				var c = result_next(r);
+				if( c == null )
+					break;
+				cache.add(c);
+			}
+			return cache.length;
+		}
+		return result_get_length(r);
+	}
+
+	function get_nfields() {
+		return result_get_nfields(r);
+	}
+
+	public function hasNext() {
+		var c = next();
+		if( c == null )
+			return false;
+		cache.push(c);
+		return true;
+	}
+
+	public function next() : Dynamic {
+		var c = cache.pop();
+		if( c != null )
+			return c;
+		return result_next(r);
+	}
+
+	public function results() : List<Dynamic> {
+		var l = new List();
+		while( true ) {
+			var c = next();
+			if( c == null )
+				break;
+			l.add(c);
+		}
+		return l;
+	}
+
+	public function getResult( n : Int ) {
+		return new String(result_get(r,n));
+	}
+
+	public function getIntResult( n : Int ) : Int {
+		return result_get_int(r,n);
+	}
+
+	public function getFloatResult( n : Int ) : Float {
+		return result_get_float(r,n);
+	}
+
+	public function getFieldsNames() : Array<String> {
+		return null;
+	}
+
+	static var result_next = cpp.Lib.load("sqlite","result_next",1);
+	static var result_get_length = cpp.Lib.load("sqlite","result_get_length",1);
+	static var result_get_nfields = cpp.Lib.load("sqlite","result_get_nfields",1);
+	static var result_get = cpp.Lib.load("sqlite","result_get",2);
+	static var result_get_int = cpp.Lib.load("sqlite","result_get_int",2);
+	static var result_get_float = cpp.Lib.load("sqlite","result_get_float",2);
+
+}
+
+@:coreApi class Sqlite {
+
+	public static function open( file : String ) : Connection {
+		return new SqliteConnection(file);
+	}
+
+}