Browse Source

added php support

Nicolas Cannasse 14 years ago
parent
commit
fd5f16559d
3 changed files with 103 additions and 7 deletions
  1. 38 6
      std/sys/db/Manager.hx
  2. 4 1
      std/sys/db/Object.hx
  3. 61 0
      std/sys/db/SpodMacros.hx

+ 38 - 6
std/sys/db/Manager.hx

@@ -79,8 +79,10 @@ class Manager<T : Object> {
 
 
 		// set the manager and ready for further init
 		// set the manager and ready for further init
 		class_proto = cast classval;
 		class_proto = cast classval;
+		#if neko
 		class_proto.prototype._manager = this;
 		class_proto.prototype._manager = this;
 		init_list.add(this);
 		init_list.add(this);
+		#end
 	}
 	}
 
 
 	public function all( ?lock: Bool ) : List<T> {
 	public function all( ?lock: Bool ) : List<T> {
@@ -247,10 +249,19 @@ class Manager<T : Object> {
 	/* ---------------------------- INTERNAL API -------------------------- */
 	/* ---------------------------- INTERNAL API -------------------------- */
 
 
 	function cacheObject( x : T, lock : Bool ) {
 	function cacheObject( x : T, lock : Bool ) {
-		addToCache(x);
-		untyped __dollar__objsetproto(x,class_proto.prototype);
-		Reflect.setField(x,cache_field,untyped __dollar__new(x));
-		untyped x._lock = lock;
+		#if neko
+		var o = untyped __dollar__new(x);
+		untyped __dollar__objsetproto(o, class_proto.prototype);
+		#else
+		var o : T = Type.createEmptyInstance(cast class_proto);
+		for( f in Reflect.fields(x) )
+			Reflect.setField(o, f, Reflect.field(x, f));
+		untyped o._manager = this;
+		#end
+		Reflect.setField(o,cache_field,x);
+		addToCache(o);
+		untyped o._lock = lock;
+		return o;
 	}
 	}
 
 
 	function make( x : T ) {
 	function make( x : T ) {
@@ -294,7 +305,7 @@ class Manager<T : Object> {
 		var c = getFromCache(r,lock);
 		var c = getFromCache(r,lock);
 		if( c != null )
 		if( c != null )
 			return c;
 			return c;
-		cacheObject(r,lock);
+		r = cacheObject(r,lock);
 		make(r);
 		make(r);
 		return r;
 		return r;
 	}
 	}
@@ -311,7 +322,7 @@ class Manager<T : Object> {
 			if( c != null )
 			if( c != null )
 				l2.add(c);
 				l2.add(c);
 			else {
 			else {
-				cacheObject(x,lock);
+				x = cacheObject(x,lock);
 				make(x);
 				make(x);
 				l2.add(x);
 				l2.add(x);
 			}
 			}
@@ -443,6 +454,27 @@ class Manager<T : Object> {
 		});
 		});
 	}
 	}
 
 
+	#if !neko
+
+	function __get( x : Dynamic, prop : String, key : String, lock ) {
+		var v = Reflect.field(x,prop);
+		if( v != null )
+			return v.value;
+		var x = unsafeGet(Reflect.field(x, key), lock);
+		Reflect.setField(x,prop,{ value : x });
+		return x;
+	}
+
+	function __set( x : Dynamic, prop : String, key : String, v : T ) {
+		Reflect.setField(x,prop,{ value : v });
+		if( v == null )
+			Reflect.setField(x,key,null);
+		else
+			Reflect.setField(x,key,Reflect.field(v,table_keys[0]));
+	}
+
+	#end
+
 	/* ---------------------------- OBJECT CACHE -------------------------- */
 	/* ---------------------------- OBJECT CACHE -------------------------- */
 
 
 	function makeCacheKey( x : T ) : String {
 	function makeCacheKey( x : T ) : String {

+ 4 - 1
std/sys/db/Object.hx

@@ -35,6 +35,9 @@ class Object {
 	var _manager(default,never) : sys.db.Manager<Dynamic>;
 	var _manager(default,never) : sys.db.Manager<Dynamic>;
 
 
 	public function new() {
 	public function new() {
+		#if php
+		if( _manager == null ) untyped _manager = Type.getClass(this).manager;
+		#end
 	}
 	}
 
 
 	public function insert() {
 	public function insert() {
@@ -48,7 +51,7 @@ class Object {
 	public function lock() {
 	public function lock() {
 		untyped _manager.doLock(this);
 		untyped _manager.doLock(this);
 	}
 	}
-	
+
 	public function delete() {
 	public function delete() {
 		untyped _manager.doDelete(this);
 		untyped _manager.doDelete(this);
 	}
 	}

+ 61 - 0
std/sys/db/SpodMacros.hx

@@ -1006,6 +1006,8 @@ class SpodMacros {
 		return { expr : ECall({ expr : EField(em,"unsafeDelete"), pos : pos },[sql]), pos : pos };
 		return { expr : ECall({ expr : EField(em,"unsafeDelete"), pos : pos },[sql]), pos : pos };
 	}
 	}
 
 
+	static var isNeko = Context.defined("neko");
+
 	public static function macroBuild() {
 	public static function macroBuild() {
 		var fields = Context.getBuildFields();
 		var fields = Context.getBuildFields();
 		var hasManager = false;
 		var hasManager = false;
@@ -1016,6 +1018,65 @@ class SpodMacros {
 					switch( f.kind ) {
 					switch( f.kind ) {
 					case FVar(t, _):
 					case FVar(t, _):
 						f.kind = FProp("dynamic", "dynamic", t);
 						f.kind = FProp("dynamic", "dynamic", t);
+						if( isNeko )
+							continue;
+						var relKey = null;
+						var relParams = [];
+						var lock = false;
+						for( p in m.params )
+							switch( p.expr ) {
+							case EConst(c):
+								switch( c ) {
+								case CIdent(i), CType(i):
+									relParams.push(i);
+								default:
+								}
+							default:
+							}
+						relKey = relParams.shift();
+						for( p in relParams )
+							if( p == "lock" )
+								lock = true;
+						// we will get an error later
+						if( relKey == null )
+							continue;
+						// generate get/set methods stubs
+						var pos = f.pos;
+						var ttype = t, tname;
+						while( true )
+							switch(ttype) {
+							case TPath(t):
+								if( t.params.length == 1 && (t.name == "Null" || t.name == "SNull") ) {
+									ttype = switch( t.params[0] ) {
+									case TPType(t): t;
+									default: throw "assert";
+									};
+									continue;
+								}
+								var p = t.pack.copy();
+								p.push(t.name);
+								if( t.sub != null ) p.push(t.sub);
+								tname = p.join(".");
+								break;
+							default:
+								Context.error("Relation type should be a type path", f.pos);
+							}
+						function e(expr) return { expr : expr, pos : pos };
+						var get = {
+							args : [],
+							params : [],
+							ret : t,
+							expr : Context.parse("return untyped "+tname+".manager.__get(this,'"+f.name+"','"+relKey+"',"+lock+")",pos),
+						};
+						var set = {
+							args : [{ name : "_v", opt : false, type : t, value : null }],
+							params : [],
+							ret : t,
+							expr : Context.parse("return untyped "+tname+".manager.__set(this,'"+f.name+"','"+relKey+"',_v)",pos),
+						};
+						var meta = [{ name : ":hide", params : [], pos : pos }];
+						fields.push({ name : "get_"+f.name, pos : pos, meta : meta, access : [APrivate], doc : null, kind : FFun(get) });
+						fields.push({ name : "set_"+f.name, pos : pos, meta : meta, access : [APrivate], doc : null, kind : FFun(set) });
 					default:
 					default:
 						Context.error("Invalid relation field type", f.pos);
 						Context.error("Invalid relation field type", f.pos);
 					}
 					}