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