Browse Source

sys.db package

Nicolas Cannasse 14 years ago
parent
commit
ae5420dc6c

+ 3 - 1
doc/CHANGES.txt

@@ -12,7 +12,6 @@
 	all : bugfix when optimizing inlined immediate function call
 	all : fixed "using" on macro function
 	all : allowed member macros functions (called as static)
-	neko : added spod_macro support
 	neko : allowed serialization of haxe.Int32 (as Int)
 	all : fixed invalid optimization of two constant numbers comparison
 	flash8 : bugfix Std.parseInt with some hex values
@@ -35,6 +34,9 @@
 	all : allow this + member variables access in local functions
 		added untyped __this__ support and transition error
 	all : added haxe.macro.MacroType
+	neko : neko.Lib.serialize/unserialize now returns bytes
+	neko : added sys.db package (crossplatform with -D spod_macro support)
+		spod_macro now uses wrappers for Bytes (require neko 1.8.2)
 
 2011-01-30: 2.07
 	all : fixed completion support with --remap

+ 1 - 1
std/haxe/web/Dispatch.hx

@@ -220,7 +220,7 @@ class Dispatch {
 				return MRDispatch;
 			default:
 				var c = i.get();
-				if( c.superClass != null && c.superClass.t.toString() == "neko.db.Object" ) {
+				if( c.superClass != null && (c.superClass.t.toString() == "neko.db.Object" || c.superClass.t.toString() == "sys.db.Object") ) {
 					var lock = switch( t ) {
 					case TType(t, _): t.get().name == "Lock";
 					default: false;

+ 216 - 0
std/neko/_std/sys/db/Mysql.hx

@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package sys.db;
+
+private class D {
+
+	static function load(fun,args) : Dynamic {
+		return neko.Lib.load(lib,fun,args);
+	}
+
+	static var lib = try { neko.Lib.load("mysql5","connect",1); "mysql5"; } catch( e : Dynamic ) "mysql";
+	public static var connect = load("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 = neko.Lib.loadLazy(lib,"result_get_fields_names",1);
+
+}
+
+private class MysqlResultSet implements sys.db.ResultSet {
+
+	public var length(getLength,null) : Int;
+	public var nfields(getNFields,null) : Int;
+	private var __r : Void;
+	private var cache : Dynamic;
+
+	public function new(r) {
+		__r = r;
+	}
+
+	private function getLength() {
+		return D.result_get_length(__r);
+	}
+
+	private function getNFields() {
+		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);
+		untyped {
+			var i = 0;
+			var l = __dollar__asize(a);
+			while( i < l ) {
+				a[i] = new String(a[i]);
+				i += 1;
+			}
+			a = Array.new1(cast a,l);
+		}
+		return a;
+	}
+
+}
+
+private class MysqlConnection implements sys.db.Connection {
+
+	private var __c : Void;
+
+	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 {
+		try {
+			var r = D.request(this.__c, untyped s.__s);
+			return new MysqlResultSet(r);
+		} catch( e : Dynamic ) {
+			untyped if( __dollar__typeof(e) == __dollar__tobject && __dollar__typeof(e.msg) == __dollar__tstring )
+				e = e.msg;
+			untyped __dollar__rethrow(e);
+			return null;
+		}
+	}
+
+	public function close() {
+		D.close(__c);
+	}
+
+	public function escape( s : String ) {
+		return new String(D.escape(__c,untyped s.__s));
+	}
+
+	public function quote( s : String ) {
+		return "'"+escape(s)+"'";
+	}
+
+	public function addValue( s : StringBuf, v : Dynamic ) {
+		var t = untyped __dollar__typeof(v);
+		if( untyped (t == __dollar__tint || t == __dollar__tnull) )
+			s.add(v);
+		else if( untyped t == __dollar__tbool )
+			s.addChar(if( v ) "1".code else "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;
+}
+
+@:core_api class Mysql {
+
+	public static function connect( params : {
+		host : String,
+		port : Int,
+		user : String,
+		pass : String,
+		socket : String,
+		database : String
+	} ) : sys.db.Connection {
+		var o = untyped {
+			host : params.host.__s,
+			port : params.port,
+			user : params.user.__s,
+			pass : params.pass.__s,
+			socket : if( params.socket == null ) null else params.socket.__s
+		};
+		var c = D.connect(o);
+		try {
+			D.select_db(c,untyped params.database.__s);
+		} catch( e : Dynamic ) {
+			D.close(c);
+			neko.Lib.rethrow(e);
+		}
+		return new MysqlConnection(c);
+	}
+
+}

+ 3 - 14
std/neko/db/Connection.hx

@@ -24,17 +24,6 @@
  */
 package neko.db;
 
-interface Connection {
-
-	function request( s : String ) : ResultSet;
-	function close() : Void;
-	function escape( s : String ) : String;
-	function quote( s : String ) : String;
-	function addValue( s : StringBuf, v : Dynamic ) : Void;
-	function lastInsertId() : Int;
-	function dbName() : String;
-	function startTransaction() : Void;
-	function commit() : Void;
-	function rollback() : Void;
-
-}
+#if !spod_macro
+typedef Connection = sys.db.Connection;
+#end

+ 0 - 2
std/neko/db/Manager.hx

@@ -30,8 +30,6 @@ typedef Manager<T : Object> = mt.db.ShardManager<T>;
 
 #elseif spod_macro
 
-typedef Manager<T : Object> = neko.db.MacroManager<T>;
-
 #else
 
 import Reflect;

+ 3 - 0
std/neko/db/Mysql.hx

@@ -23,6 +23,7 @@
  * DAMAGE.
  */
 package neko.db;
+#if !spod_macro
 
 import neko.db.Connection;
 
@@ -229,3 +230,5 @@ class Mysql {
 	}
 
 }
+
+#end

+ 3 - 10
std/neko/db/Object.hx

@@ -28,7 +28,7 @@ package neko.db;
 	SPOD Object : the persistent object base type. See the tutorial on haXe
 	website to learn how to use SPOD.
 **/
-#if spod_macro @:autoBuild(neko.db.SpodData.macroBuild()) #end
+#if spod_macro #else
 class Object #if spod_rtti implements haxe.rtti.Infos #end {
 
 /*
@@ -49,9 +49,6 @@ class Object #if spod_rtti implements haxe.rtti.Infos #end {
 		private function doSync( o : Object ) : Void;
 		private function doDelete( o : Object ) : Void;
 		private function objectToString( o : Object ) : String;
-		#if spod_macro
-		private function doLock( o : Object ) : Void;
-		#end
 	};
 
 
@@ -73,15 +70,11 @@ class Object #if spod_rtti implements haxe.rtti.Infos #end {
 	public function delete() {
 		local_manager.doDelete(this);
 	}
-	
-	#if spod_macro
-	public function lock() {
-		local_manager.doLock(this);
-	}
-	#end
 
 	public function toString() {
 		return local_manager.objectToString(this);
 	}
 
 }
+
+#end

+ 3 - 15
std/neko/db/ResultSet.hx

@@ -24,18 +24,6 @@
  */
 package neko.db;
 
-interface ResultSet {
-
-	var length(getLength,null) : Int;
-	var nfields(getNFields,null) : Int;
-
-
-	function hasNext() : Bool;
-	function next() : Dynamic;
-	function results() : List<Dynamic>;
-	function getResult( n : Int ) : String;
-	function getIntResult( n : Int ) : Int;
-	function getFloatResult( n : Int ) : Float;
-	function getFieldsNames() : Null<Array<String>>;
-
-}
+#if !spod_macro
+typedef ResultSet = sys.db.ResultSet;
+#end

+ 2 - 2
std/neko/db/Transaction.hx

@@ -23,8 +23,7 @@
  * DAMAGE.
  */
 package neko.db;
-
-import Reflect;
+#if !spod_macro
 
 class Transaction {
 
@@ -69,3 +68,4 @@ class Transaction {
 	}
 
 }
+#end

+ 3 - 14
std/php/db/Connection.hx

@@ -24,17 +24,6 @@
  */
 package php.db;
 
-interface Connection {
-
-	function request( s : String ) : ResultSet;
-	function close() : Void;
-	function escape( s : String ) : String;
-	function quote( s : String ) : String;
-	function addValue( s : StringBuf, v : Dynamic ) : Void;
-	function lastInsertId() : Int;
-	function dbName() : String;
-	function startTransaction() : Void;
-	function commit() : Void;
-	function rollback() : Void;
-
-}
+#if !spod_macro
+typedef Connection = sys.db.Connection;
+#end

+ 3 - 14
std/php/db/ResultSet.hx

@@ -24,17 +24,6 @@
  */
 package php.db;
 
-interface ResultSet {
-
-	var length(getLength,null) : Int;
-	var nfields(getNFields,null) : Int;
-
-
-	function hasNext() : Bool;
-	function next() : Dynamic;
-	function results() : List<Dynamic>;
-	function getResult( n : Int ) : String;
-	function getIntResult( n : Int ) : Int;
-	function getFloatResult( n : Int ) : Float;
-
-}
+#if !spod_macro
+typedef ResultSet = sys.db.ResultSet;
+#end

+ 2 - 0
std/php/db/Transaction.hx

@@ -24,6 +24,7 @@
  */
 package php.db;
 
+#if !spod_macro
 class Transaction {
 
 	public static function isDeadlock(e : Dynamic) {
@@ -67,3 +68,4 @@ class Transaction {
 	}
 
 }
+#end

+ 40 - 0
std/sys/db/Connection.hx

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package sys.db;
+
+interface Connection {
+
+	function request( s : String ) : ResultSet;
+	function close() : Void;
+	function escape( s : String ) : String;
+	function quote( s : String ) : String;
+	function addValue( s : StringBuf, v : Dynamic ) : Void;
+	function lastInsertId() : Int;
+	function dbName() : String;
+	function startTransaction() : Void;
+	function commit() : Void;
+	function rollback() : Void;
+
+}

File diff suppressed because it is too large
+ 14 - 12
std/sys/db/Manager.hx


+ 38 - 0
std/sys/db/Mysql.hx

@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2005-2011, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package sys.db;
+
+extern class Mysql {
+
+	public static function connect( params : {
+		host : String,
+		port : Int,
+		user : String,
+		pass : String,
+		socket : String,
+		database : String
+	} ) : sys.db.Connection;
+
+}

+ 60 - 0
std/sys/db/Object.hx

@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package sys.db;
+
+/**
+	SPOD Object : the persistent object base type. See the tutorial on haXe
+	website to learn how to use SPOD.
+**/
+@:autoBuild(sys.db.SpodData.macroBuild())
+class Object {
+
+	var _locked(default,never) : Bool;
+	var _manager(default,never) : sys.db.Manager<Dynamic>;
+
+	public function new() {
+	}
+
+	public function insert() {
+		untyped _manager.doInsert(this);
+	}
+
+	public function update() {
+		untyped _manager.doUpdate(this);
+	}
+
+	public function lock() {
+		untyped _manager.doLock(this);
+	}
+	
+	public function delete() {
+		untyped _manager.doDelete(this);
+	}
+
+	public function toString() {
+		return untyped _manager.objectToString(this);
+	}
+
+}

+ 41 - 0
std/sys/db/ResultSet.hx

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package sys.db;
+
+interface ResultSet {
+
+	var length(getLength,null) : Int;
+	var nfields(getNFields,null) : Int;
+
+
+	function hasNext() : Bool;
+	function next() : Dynamic;
+	function results() : List<Dynamic>;
+	function getResult( n : Int ) : String;
+	function getIntResult( n : Int ) : Int;
+	function getFloatResult( n : Int ) : Float;
+	function getFieldsNames() : Null<Array<String>>;
+
+}

+ 21 - 20
std/neko/db/SpodData.hx → std/sys/db/SpodData.hx

@@ -1,5 +1,5 @@
-package neko.db;
-import neko.db.SpodInfos;
+package sys.db;
+import sys.db.SpodInfos;
 import haxe.macro.Expr;
 import haxe.macro.Type.VarAccess;
 #if macro
@@ -96,11 +96,11 @@ class SpodData {
 		case TInst(c, p):
 			var name = c.toString();
 			var cl = c.get();
-			if( cl.superClass != null && cl.superClass.t.toString() == "neko.db.Object" )
+			if( cl.superClass != null && cl.superClass.t.toString() == "sys.db.Object" )
 				return name;
 		case TType(t, p):
 			var name = t.toString();
-			if( p.length == 1 && (name == "Null" || name == "neko.db.SNull" || name == "mt.db.SNull") ) {
+			if( p.length == 1 && (name == "Null" || name == "sys.db.SNull") ) {
 				isNull = true;
 				return makeSpod(p[0]);
 			}
@@ -118,7 +118,7 @@ class SpodData {
 			case "Float": DFloat;
 			case "String": DText;
 			case "Date": DDateTime;
-			case "mt.db.SFlags", "neko.db.SFlags":
+			case "sys.db.SFlags":
 				switch( p[0] ) {
 				case TEnum(e,_):
 					var cl = e.get().names;
@@ -144,10 +144,8 @@ class SpodData {
 			}
 		case TType(t, p):
 			var name = t.toString();
-			if( StringTools.startsWith(name, "neko.db.") )
-				name = name.substr(8);
-			else if( StringTools.startsWith(name, "mt.db.") )
-				name = name.substr(6);
+			if( StringTools.startsWith(name, "sys.db.") )
+				name = name.substr(7);
 			var k = types.get(name);
 			if( k != null ) return k;
 			if( p.length == 1 )
@@ -210,7 +208,7 @@ class SpodData {
 							params.push({ i : makeIdent(p), p : p.pos });
 						isNull = false;
 						var t = makeSpod(f.type);
-						if( t == null ) error("Relation type should be a neko.db.Object", f.pos);
+						if( t == null ) error("Relation type should be a sys.db.Object", f.pos);
 						var r = {
 							prop : f.name,
 							key : params.shift().i,
@@ -242,9 +240,12 @@ class SpodData {
 				t : try makeType(f.type) catch( e : String ) error(e,f.pos),
 				isNull : isNull,
 			};
-			switch( fi.t ) {
-			case DId, DUId: if( i.key == null ) i.key = [fi.name] else error("Multiple table id declaration", f.pos);
-			default:
+			var isId = switch( fi.t ) {
+			case DId, DUId: true;
+			default: fi.name == "id";
+			}
+			if( isId ) {
+				if( i.key == null ) i.key = [fi.name] else error("Multiple table id declaration", f.pos);
 			}
 			i.fields.push(fi);
 			i.hfields.set(fi.name, fi);
@@ -311,7 +312,7 @@ class SpodData {
 	}
 
 	function initManager( pos : Position ) {
-		manager = { expr : EType({ expr : EField({ expr : EConst(CIdent("neko")), pos : pos },"db"), pos : pos }, "Manager"), pos : pos };
+		manager = { expr : EType({ expr : EField({ expr : EConst(CIdent("sys")), pos : pos },"db"), pos : pos }, "Manager"), pos : pos };
 	}
 
 	inline function makeString( s : String, pos ) {
@@ -837,7 +838,7 @@ class SpodData {
 
 	public static function getInfos( t : haxe.macro.Type ) {
 		var c = switch( t ) {
-		case TInst(c, _): if( c.toString() == "neko.db.Object" ) return null; c;
+		case TInst(c, _): if( c.toString() == "sys.db.Object" ) return null; c;
 		default: return null;
 		};
 		var i = inst;
@@ -855,7 +856,7 @@ class SpodData {
 	public static function addRtti() : Array<Field> {
 		if( RTTI ) return null;
 		RTTI = true;
-		Context.getType("neko.db.SpodInfos");
+		Context.getType("sys.db.SpodInfos");
 		Context.onGenerate(function(types) {
 			for( t in types )
 				switch( t ) {
@@ -863,7 +864,7 @@ class SpodData {
 					var c = c.get();
 					var cur = c.superClass;
 					while( cur != null ) {
-						if( cur.t.toString() == "neko.db.Object" )
+						if( cur.t.toString() == "sys.db.Object" )
 							break;
 						cur = cur.t.get().superClass;
 					}
@@ -886,7 +887,7 @@ class SpodData {
 		switch( t ) {
 		case TInst(c, p):
 			while( true ) {
-				if( c.toString() == "neko.db.MacroManager" ) {
+				if( c.toString() == "sys.db.Manager" ) {
 					param = p[0];
 					break;
 				}
@@ -896,7 +897,7 @@ class SpodData {
 				p = csup.params;
 			}
 		case TType(t, p):
-			if( p.length == 1 && t.toString() == "neko.db.Manager" )
+			if( p.length == 1 && t.toString() == "sys.db.Manager" )
 				param = p[0];
 		default:
 		}
@@ -1000,7 +1001,7 @@ class SpodData {
 			var p = inst.pos;
 			var tinst = TPath( { pack : inst.pack, name : inst.name, sub : null, params : [] } );
 			var path = inst.pack.copy().concat([inst.name]).join(".");
-			var enew = { expr : ENew( { pack : ["neko", "db"], name : "Manager", sub : null, params : [TPType(tinst)] }, [Context.parse(path, p)]), pos : p }
+			var enew = { expr : ENew( { pack : ["sys", "db"], name : "Manager", sub : null, params : [TPType(tinst)] }, [Context.parse(path, p)]), pos : p }
 			fields.push({ name : "manager", meta : [], kind : FVar(null,enew), doc : null, access : [AStatic,APublic], pos : p });
 		}
 		return fields;

+ 1 - 1
std/neko/db/SpodInfos.hx → std/sys/db/SpodInfos.hx

@@ -22,7 +22,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * DAMAGE.
  */
-package neko.db;
+package sys.db;
 
 enum SpodType {
 	DId;

+ 73 - 0
std/sys/db/Transaction.hx

@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+package sys.db;
+
+class Transaction {
+
+	public static function isDeadlock(e : Dynamic) {
+		return Std.is(e,String) && (~/Deadlock found/.match(e) || ~/Lock wait timeout/.match(e));
+	}
+
+	private static function runMainLoop(mainFun,logError,count) {
+		try {
+			mainFun();
+		} catch( e : Dynamic ) {
+			if( count > 0 && isDeadlock(e) ) {
+				Manager.cleanup();
+				Manager.cnx.rollback(); // should be already done, but in case...
+				Manager.cnx.startTransaction();
+				runMainLoop(mainFun,logError,count-1);
+				return;
+			}
+			if( logError == null ) {
+				Manager.cnx.rollback();
+				#if neko
+				neko.Lib.rethrow(e);
+				#else
+				throw e;
+				#end
+			}
+			logError(e); // should ROLLBACK if needed
+		}
+	}
+
+	public static function main( cnx, mainFun : Void -> Void, logError : Dynamic -> Void ) {
+		Manager.initialize();
+		Manager.cnx = cnx;
+		Manager.cnx.startTransaction();
+		runMainLoop(mainFun,logError,3);
+		try {
+			Manager.cnx.commit();
+		} catch( e : String ) {
+			// sqlite can have errors on commit
+			if( ~/Database is busy/.match(e) )
+				logError(e);
+		}
+		Manager.cnx.close();
+		Manager.cnx = null;
+		Manager.cleanup();
+	}
+
+}

+ 53 - 8
std/neko/db/Types.hx → std/sys/db/Types.hx

@@ -22,35 +22,80 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * DAMAGE.
  */
-package neko.db;
+package sys.db;
 
 // basic types
+
+/** int with auto increment **/
 typedef SId = Int
-typedef SInt = Int
+
+/** int unsigned with auto increment **/
 typedef SUId = Int
-typedef SUInt = Int
+
+/** big int with auto increment **/
 typedef SBigId = Float
+
+typedef SInt = Int
+
+typedef SUInt = Int
+
 typedef SBigInt = Float
+
+/** single precision float **/
 typedef SSingle = Float
+
+/** double precision float **/
 typedef SFloat = Float
+
+/** use tinyint(1) to distinguish with int **/
 typedef SBool = Bool
+
+/** same as varchar(n) **/
 typedef SString<Const> = String
+
+/** date only, use SDateTime for date+time **/
 typedef SDate = Date
+
+/** mysql DateTime **/
 typedef SDateTime = Date
+
+/** TinyText (up to 255 bytes) **/
 typedef STinyText = String
+
+/** Text (up to 64KB) **/
 typedef SSmallText = String
+
+/** MediumText (up to 24MB) **/
 typedef SText = String
-typedef SSmallBinary = String
-typedef SLongBinary = String
-typedef SBinary = String
-typedef SBytes<Const> = String
+
+/** Blob type (up to 64KB) **/
+typedef SSmallBinary = haxe.io.Bytes
+
+/** LongBlob type (up to 4GB) **/
+typedef SLongBinary = haxe.io.Bytes
+
+/** MediumBlob type (up to 24MB) **/
+typedef SBinary = haxe.io.Bytes
+
+/** same as binary(n) **/
+typedef SBytes<Const> = haxe.io.Bytes
+
+/** TinyInt [-128...127] **/
 typedef STinyInt = Int
 
 // extra
+
+/** specify that this field is nullable **/
 typedef SNull<T> = T
+
+/** specify that the integer use custom encoding **/
 typedef SEncoded = Int
+
+/** haxe Serialized string **/
 typedef SSerialized = String
-typedef SNekoSerialized = String
+
+/** native neko serialized bytes **/
+typedef SNekoSerialized = haxe.io.Bytes
 
 @:native("Int")
 extern class SFlags<T> {

Some files were not shown because too many files changed in this diff