rev 417 - in trunk: . include/prothon modules/Prosist src

SVN User <[email protected]> Mon, 26 Apr 2004 00:23:15 -0400
Newsgroups gmane.comp.lang.prothon.cvs
Message-ID <[email protected]>
Author: mark
Date: 2004-04-26 00:23:13 -0400 (Mon, 26 Apr 2004)
New Revision: 417

Modified:
   trunk/STATUS.txt
   trunk/include/prothon/prothon.h
   trunk/include/prothon/prothon_dll.h
   trunk/modules/Prosist/Prosist.c
   trunk/src/object.c
Log:
added Prosist rollBack() untested

Modified: trunk/STATUS.txt
===================================================================
--- trunk/STATUS.txt	2004-04-26 03:57:56 UTC (rev 416)
+++ trunk/STATUS.txt	2004-04-26 04:23:13 UTC (rev 417)
@@ -125,25 +125,9 @@
 pass not really needed, empty statements allowed
 attribute inheritance gives access to built-ins in root_globals, not built-ins module
 for x in 5:
-support /* */ comments
+support /* */ comments	
 
 
-  ---------- missing functions ------------
- 
- s.sort!([cmpFct]) 	sort the items of s in place 
-
-d.clear!() 			remove all items from d  
-d.copy() 			a shallow copy of d  
-d.has_key(k) 		1 if d has key k, else 0  
-d.items() 			a copy of d's list of (key, item) pairs (2) 
-d.keys() 			a copy of d's list of keys (2) 
-d1.update!(d2) 		for k, v in d2.items(): d1[k] = v (3) 
-d.values() 			a copy of d's list of values (2) 
-d.get(k,defaultval)	the item of d with key k 
-% operator (sprintf)
-	
-
-
 --------------  built-in functions ----------------
 
 
@@ -155,13 +139,7 @@
 apply(f, args[, keywords])
                 Call func/method <f> with args <args> and optional keywords
 
-callable(x)     Returns 1 if x callable, else 0.
 
-chr(i)          Return one-character string whose ASCII code is
-                integer i
-
-cmp(x,y)        Return neg, zero, pos if x <, ==, > to y
-
 coerce(x,y)     Return a tuple of the two numeric arguments converted to
                 a common type.
 
@@ -194,15 +172,9 @@
 
 execfile(file[, globals[, locals]])
                 Execute a file without creating a new module, unlike import.
-filter(function, sequence)
-                Construct a list from those elements of <sequence> for which
-                <function> returns true. <function> takes one parameter.
 
 float(x)        Convert a number or a string to floating point. 
 
-getattr(object, name[, default]))    [<default> arg added in 1.5.2]
-                Get attr called <name> from <object>, e.g. getattr(x, 'f') <=> x.f).
-                If not found, raise AttributeError or return <default> if specified.
                 
 globals()       Returns a dictionary containing current global variables.
 
@@ -225,8 +197,6 @@
                 return true if <obj> is an instance of <class>
 issubclass(class1, class2)
                 return true if <class1> is derived from <class2>
-len(s)          Return the length (the number of items) of an object
-                (sequence or dictionary).
 
 list(sequence)
                 Convert <sequence> into a list. If already a list,
@@ -235,26 +205,12 @@
 
 long(x)         Convert a number or a string to a long integer.
 
-map(function, list, ...)
-                Apply <function> to every item of <list> and return a list
-                of the results.  If additional arguments are passed, 
-                <function> must take that many arguments and it is given
-                to <function> on each call.
-
 max(s)          Return the largest item of a non-empty sequence.
 
 min(s)          Return the smallest item of a non-empty sequence.
 
 oct(x)          Convert a number to an octal string.
 
-open(filename [, mode='r', [bufsize=<implementation dependent>]])
-                Return a new file object. First two args are same as 
-                those for C's "stdio open" function. <bufsize> is 0
-                for unbuffered, 1 for line-buffered, negative for
-                sys-default, all else, of (about) given size.
-
-ord(c)          Return integer ASCII value of <c> (str of len 1).
-
 pow(x, y [, z]) Return x to power y [modulo z]. See also ** operator.
 
 range(start [,end [, step]])
@@ -278,10 +234,6 @@
                 correct but had an error in initialization, must
                 import it one more time before calling reload().
 
-repr(object)    Return a string containing a printable representation
-                of an object. Equivalent to `object` (using
-                backquotes).
-
 round(x,n=0)    Return the floating point value x rounded to n digits
                         after the decimal point.
 
@@ -293,6 +245,7 @@
 slice([start,] stop[, step])
                 Return a slice object representing a range, with R/O
                 attributes: start, stop, step.
+
 str(object)     Return a string containing a nicely printable
                 representation of an object.
 

Modified: trunk/include/prothon/prothon.h
===================================================================
--- trunk/include/prothon/prothon.h	2004-04-26 03:57:56 UTC (rev 416)
+++ trunk/include/prothon/prothon.h	2004-04-26 04:23:13 UTC (rev 417)
@@ -451,6 +451,11 @@
 obj_p new_object(isp ist, obj_p proto);
 #define NEW_OBJ(proto) new_object(ist, proto)
 
+// COPY_OBJECT_DATA: Copy object data from one object to another
+// Destination object (copy) must already exist.
+// Clobbers binary data in dest object (copy)
+void copy_object_data(isp ist, obj_p copy, obj_p obj);
+
 // GET_ATTR: Find attr in object that matches a key and return the attr value.
 // Searches object for attr with key that matches the given key symbol object.
 // If no attr is found with a matching key, then NULL is returned.

Modified: trunk/include/prothon/prothon_dll.h
===================================================================
--- trunk/include/prothon/prothon_dll.h	2004-04-26 03:57:56 UTC (rev 416)
+++ trunk/include/prothon/prothon_dll.h	2004-04-26 04:23:13 UTC (rev 417)
@@ -103,6 +103,7 @@
 	obj_p		(*call_func1_f)(isp ist, obj_p self, obj_p sym, obj_p parm);
 	obj_p   	(*sym)(isp ist, char* symbol);
 	obj_p		(*new_object)(isp ist, obj_p proto);
+	void		(*copy_object_data)(isp ist, obj_p copy, obj_p obj);
 	void		(*set_obj_doc_f)(isp ist, obj_p obj, char* str);
 	obj_p	    (*dict_keys_values)(isp ist, obj_p dict_obj, int key_flg);
 	obj_p		(*check_exceptions)(isp ist);
@@ -262,6 +263,7 @@
 #define list8				(*services->list8)
 #define raise_exception		(*services->raise_exception)
 #define new_object			(*services->new_object)
+#define copy_object_data	(*services->copy_object_data)
 #define set_obj_doc_f		(*services->set_obj_doc_f)
 #define pr_malloc			(*services->pr_malloc)
 #define pr_realloc			(*services->pr_realloc)

Modified: trunk/modules/Prosist/Prosist.c
===================================================================
--- trunk/modules/Prosist/Prosist.c	2004-04-26 03:57:56 UTC (rev 416)
+++ trunk/modules/Prosist/Prosist.c	2004-04-26 04:23:13 UTC (rev 417)
@@ -370,13 +370,27 @@
 	del_unlock(olst);
 }
 
-//******************************** append_store_refs ****************************
-void append_store_refs( isp ist, psrec_p psrecp, obj_p obj, 
-					    int objidx, obj_p store_refs, int commit_flg ) {
+//******************************** unlock_list ********************************
+void unlock_list(isp ist, obj_p olst) {
+	int i, llen = (int) list_len(ist, olst);
+	for(i=0; i < llen; i++) {					
+		obj_p item = list_item(ist, olst, i);
+		if (item != PSNONE) {
+			if (has_proto_QUES(ist, item, MutWrap_OBJ))
+				item = (obj_p) item->data.ptr;
+			read_unlock(ist, item);				
+		}
+	}											
+	del_unlock(olst);
+}
+
+//******************************** append_refs ********************************
+void append_refs( isp ist, psrec_p psrecp, obj_p obj, 
+					    int objidx, obj_p store_refs, int append_all, int rback_flg ) {
 	psid_t id=-1;
 	attr_key_t key;
-	obj_p mw_obj, id_obj=NULL, id_tuple, proxy_obj;
-	int i, plen, tuple_type=FALSE, obj_known = FALSE;
+	obj_p mw_obj, id_obj=NULL, id_tuple, proxy_obj = NULL;
+	int i, plen, tuple_type=FALSE, obj_known = FALSE, reuse_proxy, repair_obj;
 
 	mw_obj = NEW_MW(obj);
 	id_obj = dict_item(ist, psrecp->obj_to_id, mw_obj);
@@ -384,8 +398,10 @@
 		id = (psid_t) id_obj->data.i64;
 		obj_known = TRUE;
 	}
+	reuse_proxy = obj_known && rback_flg && is_archived(obj);
+	repair_obj  = obj_known && rback_flg && !is_archived(obj);
 
-	if (obj == PSNONE || (!commit_flg && obj_known)) {
+	if (obj == PSNONE || !append_all && obj_known) {
 		list_item_set(ist, store_refs, objidx, PSNONE);
 		del_unlock(mw_obj);
 		return;
@@ -403,7 +419,7 @@
 		char *s1, *s2;
 		apr_datum_t key, value;
 		ADD_BUF_DECLARE;
-		if (commit_flg & obj_known) 
+		if (append_all & obj_known) 
 			goto endidobj;
 		dict_add(ist, psrecp->obj_to_id,   mw_obj,   id_obj);
 		if (ist->exception_obj) { del_unlock(mw_obj); return; }
@@ -443,33 +459,68 @@
 		del_unlock(mw_obj);
 		return;
 	}
-	proxy_obj = call_func0(ist, obj, SYM(__TOSTORPROXY__)); if_exc_return;
-	
-	if (proxy_obj == PSNONE || is_unclonable(proxy_obj)) { 
-		list_item_set(ist, store_refs, objidx, PSNONE);
-		read_unlock(ist, obj);
-		del_unlock(mw_obj); 
-		del_unlock(id_obj);
-		del_unlock(proxy_obj); 
-		return;
+	if (repair_obj || reuse_proxy) {
+		proxy_obj = dict_item(ist, psrecp->obj_to_proxy, mw_obj);
+		if (ist->exception_obj) {
+			del_unlock(mw_obj); 
+			del_unlock(id_obj);
+			return;
+		}
+		if (!proxy_obj) {
+			raise_exception(ist, ProsistExc_OBJ, "known rollback object not found");
+			del_unlock(mw_obj); 
+			del_unlock(id_obj);
+			return;
+		}
 	}
-	if (proxy_obj->data_type == DATA_TYPE_DATAPTR) {
-		tuple_type = has_proto_QUES(ist, proxy_obj, OBJ(TUPLE_PROTO));
-		if (!tuple_type && !has_proto_QUES(ist, proxy_obj, OBJ(STRING_PROTO))) {
-			raise_exception(ist, ProsistExc_OBJ, "unstorable object (data ptr) found in tree");
+	if (repair_obj) {
+		obj_p res = call_func0(ist, proxy_obj, SYM(__FROMSTORPROXY__));
+		if (!res) {
+			raise_exception(ist, ProsistExc_OBJ, "__fromStorProxy__ not found on proxy obj");
 			del_unlock(mw_obj); 
 			del_unlock(id_obj);
+			return;
+		}
+		if (obj != proxy_obj) {
+			if (obj->data_type == DATA_TYPE_DATAPTR && obj->data.ptr) {
+				pr_free(obj->data.ptr);
+			}
+			copy_object_data(ist, obj, proxy_obj);
+		}
+		proxy_obj = obj;
+	}
+	if (!proxy_obj) {
+		proxy_obj = call_func0(ist, obj, SYM(__TOSTORPROXY__));
+		if (ist->exception_obj) {
+			del_unlock(mw_obj); 
+			del_unlock(id_obj);
+			return;
+		}
+		if (proxy_obj == PSNONE || is_unclonable(proxy_obj)) { 
+			list_item_set(ist, store_refs, objidx, PSNONE);
+			read_unlock(ist, obj);
+			del_unlock(mw_obj); 
+			del_unlock(id_obj);
 			del_unlock(proxy_obj); 
 			return;
 		}
+		if (proxy_obj->data_type == DATA_TYPE_DATAPTR) {
+			tuple_type = has_proto_QUES(ist, proxy_obj, OBJ(TUPLE_PROTO));
+			if (!tuple_type && !has_proto_QUES(ist, proxy_obj, OBJ(STRING_PROTO))) {
+				raise_exception(ist, ProsistExc_OBJ, "unstorable object (data ptr) found in tree");
+				del_unlock(mw_obj); 
+				del_unlock(id_obj);
+				del_unlock(proxy_obj); 
+				return;
+			}
+		}
+		dict_add(ist, psrecp->obj_to_proxy, mw_obj,    proxy_obj);
+		if (ist->exception_obj) { del_unlock(mw_obj); return; }
+		dict_add(ist, psrecp->obj_to_id,    mw_obj,    id_obj);
+		if (ist->exception_obj) { del_unlock(mw_obj); return; }
+		dict_add(ist, psrecp->id_to_obj,    id_obj, obj);
+		if (ist->exception_obj) { del_unlock(mw_obj); return; }
 	}
-	dict_add(ist, psrecp->obj_to_proxy, mw_obj,    proxy_obj);
-	if (ist->exception_obj) { del_unlock(mw_obj); return; }
-	dict_add(ist, psrecp->obj_to_id,    mw_obj,    id_obj);
-	if (ist->exception_obj) { del_unlock(mw_obj); return; }
-	dict_add(ist, psrecp->id_to_obj,    id_obj, obj);
-	if (ist->exception_obj) { del_unlock(mw_obj); return; }
-
 	del_unlock(mw_obj);
 
 	plen = proto_len(ist, proxy_obj);
@@ -477,7 +528,7 @@
 		obj_p proto = proto_item(ist, proxy_obj, i);
 		mw_obj = NEW_MW(proto);
 		if ( !is_unclonable(proto) && 
-			 (commit_flg || !dict_item(ist, psrecp->obj_to_id, mw_obj)) )
+			 (append_all || !dict_item(ist, psrecp->obj_to_id, mw_obj)) )
 			list_append(ist, store_refs, proto);
 		del_unlock(mw_obj);
 		if_exc_return;
@@ -487,7 +538,7 @@
 		obj_p attr = attr_value_by_key(ist, proxy_obj, key);
 		mw_obj = NEW_MW(attr);
 		if ( !is_unclonable(attr) && 
-			 (commit_flg || !dict_item(ist, psrecp->obj_to_id, mw_obj)) )
+			 (append_all || !dict_item(ist, psrecp->obj_to_id, mw_obj)) )
 			list_append(ist, store_refs, attr);
 		del_unlock(mw_obj);
 		if_exc_return;
@@ -499,7 +550,7 @@
 			obj_p item = list_item(ist, proxy_obj, i);
 			mw_obj = NEW_MW(item);
 			if ( !is_unclonable(item) && 
-			     (commit_flg || !dict_item(ist, psrecp->obj_to_id, mw_obj)) )
+			     (append_all || !dict_item(ist, psrecp->obj_to_id, mw_obj)) )
 				list_append(ist, store_refs, item);
 			del_unlock(mw_obj);
 			if_exc_return;
@@ -738,7 +789,7 @@
 	list_append(ist, store_refs, psrecp->root);
 	for (i=0; i < (int) list_len(ist, store_refs); i++) {
 		obj_p item = list_item(ist, store_refs, i);
-		append_store_refs(ist, psrecp, item, i, store_refs, FALSE);
+		append_refs(ist, psrecp, item, i, store_refs, FALSE, FALSE);
 		IF_EXC_UNLKOBJS_RTRN();
 	}
 	llen = (int) list_len(ist, store_refs);
@@ -768,7 +819,7 @@
 	list_append(ist, store_refs, psrecp->root);
 	for (i=0; i < (int) list_len(ist, store_refs); i++) {
 		obj_p item = list_item(ist, store_refs, i);
-		append_store_refs(ist, psrecp, item, i, store_refs, TRUE);
+		append_refs(ist, psrecp, item, i, store_refs, TRUE, FALSE);
 		IF_EXC_UNLKOBJS_RTRN();
 	}
 	llen = (int) list_len(ist, store_refs);
@@ -784,6 +835,33 @@
 #endif
 }
 
+#define IF_EXC_UNLKLIST_RTRN				\
+	if (ist->exception_obj) {				\
+		unlock_list(ist, rollback_refs);	\
+		return;								\
+	}
+
+//******************************** rollback_db ************************************
+void rollback_db(isp ist, psrec_p psrecp) {
+	obj_p rollback_refs;
+	int i;
+#ifdef PROSIST_DEBUG
+	printf ("\nStarting rollback_db\n\n");
+#endif
+	rollback_refs = new_list_obj(ist, 20);
+	list_append(ist, rollback_refs, psrecp->root);
+	IF_EXC_UNLKLIST_RTRN;
+	for (i=0; i < (int) list_len(ist, rollback_refs); i++) {
+		obj_p item = list_item(ist, rollback_refs, i);
+		append_refs(ist, psrecp, item, i, rollback_refs, TRUE, TRUE);
+		IF_EXC_UNLKLIST_RTRN;
+	}
+	unlock_list(ist, rollback_refs);
+#ifdef PROSIST_DEBUG
+	printf ("\nEnding rollback_db\n\n");
+#endif
+}
+
 //******************************** load_db ************************************
 obj_p load_db(isp ist, psrec_p psrecp) {
 	int llen, idx = 0;
@@ -882,7 +960,7 @@
 	psrecp->idobj_to_id = NEW_DICT(4*INITIAL_OBJ_COUNT);
 	psrecp->id_to_obj   = NEW_DICT(4*INITIAL_OBJ_COUNT);
 	psrecp->obj_to_id   = NEW_DICT(4*INITIAL_OBJ_COUNT);
-	psrecp->obj_to_proxy     = NEW_DICT(4*INITIAL_OBJ_COUNT);
+	psrecp->obj_to_proxy = NEW_DICT(4*INITIAL_OBJ_COUNT);
 
 	if (root_obj == OBJ(NONE)) {
 		root_obj = psrecp->root = load_db(ist, psrecp);
@@ -899,14 +977,17 @@
 	read_lock(ist, self);
 	return OBJ(NONE);
 }
-/*
-DEF(DB, abort, NULL) {
-	dbdata_p dbdatap = self->data.ptr;
-	if (dbdatap)
-		trans_abort(ist, dbdatap);
+
+DEF(Prosist, rollBack, NULL) {
+	psrec_p psrecp = self->data.ptr;
+	if (psrecp) 
+		rollback_db(ist, psrecp);
+	else {
+		raise_exception(ist, ProsistExc_OBJ, "rollBack attempted on closed database");
+		return NULL;
+	}
 	return self;
 }
-*/
 
 DEF(Prosist, commit, NULL) {
 	psrec_p psrecp = self->data.ptr;
@@ -957,6 +1038,7 @@
 {
 	MODULE_SUB_INIT(Prosist);
 	MODULE_ADD_SYM(Prosist, __init__);
+	MODULE_ADD_SYM(Prosist, rollBack);
 	MODULE_ADD_SYM(Prosist, commit);
 	MODULE_ADD_SYM(Prosist, close);
 	MODULE_ADD_SYM(Prosist, closed_QUES);

Modified: trunk/src/object.c
===================================================================
--- trunk/src/object.c	2004-04-26 03:57:56 UTC (rev 416)
+++ trunk/src/object.c	2004-04-26 04:23:13 UTC (rev 417)
@@ -158,6 +158,7 @@
 	dll_services.list8			  = list8;		
 	dll_services.raise_exception  = raise_exception;
 	dll_services.new_object       = new_object;
+	dll_services.copy_object_data = copy_object_data;
 	dll_services.set_obj_doc_f    = set_obj_doc_f;
 	dll_services.obj_malloc		  = obj_malloc;
 	dll_services.obj_realloc      = obj_realloc;
@@ -261,6 +262,28 @@
 	return obj;
 }
 
+//********************************* copy_object_data **************************
+// clobbers data section of dest (copy) object
+void copy_object_data(isp ist, obj_p copy, obj_p obj) {
+	attr_p new_attrp, attrp;
+	rdlock_rtrn(obj);
+	if_wrlock(copy) { read_unlock(ist, obj); return; }
+	memcpy(copy, obj, sizeof(*obj)-sizeof(obj->next_obj));
+	copy->archived       = FALSE;
+	copy->del_locked     = TRUE;
+	copy->rdlock_cnt     = 0;
+	copy->wrlock_req_cnt = 0;
+	copy->wrlock		  = 0;
+	if (obj->has_attrs) {
+		size_t size;
+		attrp = obj->attr_proto.attrs;
+		size = attr_tsize(attrp)*sizeof(attr_t);
+		copy->attr_proto.attrs = new_attrp = pr_malloc(size);
+		memcpy(new_attrp, attrp, size);
+	}
+	write_unlock(ist, copy);
+	read_unlock(ist, obj);
+}
 
 //********************************* copy_object ******************************
 // clones everything but data pointed to by data.ptr