Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
ZEO
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
ZEO
Commits
6f3861e4
Commit
6f3861e4
authored
Feb 14, 1997
by
Jim Fulton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
parent
106d402b
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
1767 additions
and
0 deletions
+1767
-0
src/Persistence/cPersistence.c
src/Persistence/cPersistence.c
+589
-0
src/ZODB/cPersistence.c
src/ZODB/cPersistence.c
+589
-0
src/persistent/cPersistence.c
src/persistent/cPersistence.c
+589
-0
No files found.
src/Persistence/cPersistence.c
0 → 100644
View file @
6f3861e4
/*
$Id: cPersistence.c,v 1.1 1997/02/14 20:24:55 jim Exp $
C Persistence Module
Copyright
Copyright 1996 Digital Creations, L.C., 910 Princess Anne
Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
rights reserved. Copyright in this software is owned by DCLC,
unless otherwise indicated. Permission to use, copy and
distribute this software is hereby granted, provided that the
above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear. Note that
any product, process or technology described in this software
may be the subject of other Intellectual Property rights
reserved by Digital Creations, L.C. and are not licensed
hereunder.
Trademarks
Digital Creations & DCLC, are trademarks of Digital Creations, L.C..
All other trademarks are owned by their respective companies.
No Warranty
The software is provided "as is" without warranty of any kind,
either express or implied, including, but not limited to, the
implied warranties of merchantability, fitness for a particular
purpose, or non-infringement. This software could include
technical inaccuracies or typographical errors. Changes are
periodically made to the software; these changes will be
incorporated in new editions of the software. DCLC may make
improvements and/or changes in this software at any time
without notice.
Limitation Of Liability
In no event will DCLC be liable for direct, indirect, special,
incidental, economic, cover, or consequential damages arising
out of the use of or inability to use this software even if
advised of the possibility of such damages. Some states do not
allow the exclusion or limitation of implied warranties or
limitation of liability for incidental or consequential
damages, so the above limitation or exclusion may not apply to
you.
If you have questions regarding this software,
contact:
Jim Fulton, jim@digicool.com
Digital Creations L.C.
(540) 371-6909
Full description
$Log: cPersistence.c,v $
Revision 1.1 1997/02/14 20:24:55 jim
*** empty log message ***
*/
static
char
*
what_string
=
"$Id: cPersistence.c,v 1.1 1997/02/14 20:24:55 jim Exp $"
;
#include <time.h>
#include "Python.h"
#include "ExtensionClass.h"
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
static
PyObject
*
py_store
,
*
py_oops
,
*
py_keys
,
*
py_setstate
,
*
py___changed__
,
*
py___dict__
,
*
py_one
;
static
void
init_strings
()
{
#define INIT_STRING(S) py_ ## S = PyString_FromString(#S)
INIT_STRING
(
store
);
INIT_STRING
(
oops
);
INIT_STRING
(
keys
);
INIT_STRING
(
setstate
);
INIT_STRING
(
__changed__
);
INIT_STRING
(
__dict__
);
py_one
=
PyInt_FromLong
(
1
);
#undef INIT_STRING
}
static
PyObject
*
callmethod
(
PyObject
*
self
,
PyObject
*
name
)
{
if
(
self
=
PyObject_GetAttr
(
self
,
name
))
ASSIGN
(
self
,
PyObject_CallObject
(
self
,
NULL
));
return
self
;
}
static
PyObject
*
callmethod1
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
arg
)
{
if
((
self
=
PyObject_GetAttr
(
self
,
name
))
&&
(
name
=
PyTuple_New
(
1
)))
{
PyTuple_SET_ITEM
(
name
,
0
,
arg
);
ASSIGN
(
self
,
PyObject_CallObject
(
self
,
name
));
PyTuple_SET_ITEM
(
name
,
0
,
NULL
);
Py_DECREF
(
name
);
}
return
self
;
}
static
PyObject
*
callmethod2
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
arg
,
PyObject
*
arg2
)
{
if
((
self
=
PyObject_GetAttr
(
self
,
name
))
&&
(
name
=
PyTuple_New
(
2
)))
{
PyTuple_SET_ITEM
(
name
,
0
,
arg
);
PyTuple_SET_ITEM
(
name
,
1
,
arg2
);
ASSIGN
(
self
,
PyObject_CallObject
(
self
,
name
));
PyTuple_SET_ITEM
(
name
,
0
,
NULL
);
PyTuple_SET_ITEM
(
name
,
1
,
NULL
);
Py_DECREF
(
name
);
}
return
self
;
}
/* ----------------------------------------------------- */
/* Declarations for objects of type Persistent */
typedef
struct
{
PyObject_HEAD
PyObject
*
oid
;
PyObject
*
jar
;
PyObject
*
rtime
;
time_t
atime
;
int
state
;
#define GHOST_STATE -1
#define UPTODATE_STATE 0
#define CHANGED_STATE 1
}
Perobject
;
staticforward
PyExtensionClass
Pertype
;
staticforward
PyExtensionClass
TPertype
;
/* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- */
static
char
Per___changed____doc__
[]
=
"__changed__([flag]) -- Flag or determine whether an object has changed
\n
"
"
\n
"
"If a value is specified, then it should indicate whether an
\n
"
"object has or has not been changed. If no value is specified,
\n
"
"then the return value will indicate whether the object has
\n
"
"changed.
\n
"
;
static
PyObject
*
changed_args
=
(
PyObject
*
)
Per___changed____doc__
;
static
PyObject
*
Per___changed__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
o
;
if
(
args
)
{
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
o
))
return
NULL
;
if
(
self
->
state
!=
GHOST_STATE
)
self
->
state
=
PyObject_IsTrue
(
o
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
else
return
PyInt_FromLong
(
self
->
state
==
CHANGED_STATE
);
}
static
char
Per___save____doc__
[]
=
"__save__() -- Update the object in a persistent database."
;
static
PyObject
*
Per___save__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
if
(
self
->
oid
&&
self
->
jar
&&
self
->
state
!=
GHOST_STATE
)
return
callmethod1
(
self
->
jar
,
py_store
,(
PyObject
*
)
self
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
char
Per___inform_commit____doc__
[]
=
"__inform_commit__(transaction,start_time) -- Commit object changes"
;
static
char
Per___inform_abort____doc__
[]
=
"__inform_abort__(transaction,start_time) -- Abort object changes"
;
static
PyObject
*
Per___inform_abort__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
transaction
,
*
start_time
;
UNLESS
(
PyArg_Parse
(
args
,
"(OO)"
,
&
transaction
,
&
start_time
))
return
NULL
;
if
(
self
->
oid
&&
self
->
jar
&&
self
->
state
!=
GHOST_STATE
)
{
args
=
callmethod2
(
self
->
jar
,
py_oops
,(
PyObject
*
)
self
,
start_time
);
if
(
args
)
Py_DECREF
(
args
);
else
PyErr_Clear
();
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
char
Per__p___init____doc__
[]
=
"_p___init__(oid,jar) -- Initialize persistence management data"
;
static
PyObject
*
Per__p___init__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
oid
,
*
jar
;
UNLESS
(
PyArg_Parse
(
args
,
"(OO)"
,
&
oid
,
&
jar
))
return
NULL
;
Py_INCREF
(
oid
);
Py_INCREF
(
jar
);
ASSIGN
(
self
->
oid
,
oid
);
ASSIGN
(
self
->
jar
,
jar
);
self
->
state
=
GHOST_STATE
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
Per__getstate__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
__dict__
;
UNLESS
(
PyArg_Parse
(
args
,
""
))
return
NULL
;
/* Update state, if necessary */
if
(
self
->
state
==
GHOST_STATE
&&
self
->
jar
)
{
PyObject
*
r
;
self
->
state
=
UPTODATE_STATE
;
UNLESS
(
r
=
callmethod1
(
self
->
jar
,
py_setstate
,(
PyObject
*
)
self
))
{
self
->
state
=
GHOST_STATE
;
return
NULL
;
}
Py_DECREF
(
r
);
}
UNLESS
(
__dict__
=
PyObject_GetAttr
((
PyObject
*
)
self
,
py___dict__
))
return
NULL
;
if
(
!
PyObject_IsTrue
(
__dict__
))
{
Py_DECREF
(
__dict__
);
__dict__
=
Py_None
;
Py_INCREF
(
__dict__
);
}
return
__dict__
;
}
static
PyObject
*
Per__setstate__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
__dict__
,
*
v
,
*
keys
=
0
,
*
key
=
0
,
*
e
=
0
;
int
l
,
i
;
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
v
))
return
NULL
;
self
->
state
=
UPTODATE_STATE
;
if
(
v
!=
Py_None
)
{
UNLESS
(
__dict__
=
PyObject_GetAttr
((
PyObject
*
)
self
,
py___dict__
))
goto
err
;
UNLESS
(
keys
=
callmethod
(
v
,
py_keys
))
goto
err
;
UNLESS
(
-
1
!=
(
l
=
PyObject_Length
(
keys
)))
goto
err
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
UNLESS_ASSIGN
(
key
,
PySequence_GetItem
(
keys
,
i
))
goto
err
;
UNLESS_ASSIGN
(
e
,
PyObject_GetItem
(
v
,
key
))
goto
err
;
UNLESS
(
-
1
!=
PyObject_SetItem
(
__dict__
,
key
,
e
))
goto
err
;
}
Py_XDECREF
(
key
);
Py_XDECREF
(
e
);
Py_DECREF
(
keys
);
Py_DECREF
(
__dict__
);
}
Py_INCREF
(
Py_None
);
return
Py_None
;
err:
self
->
state
=
GHOST_STATE
;
Py_XDECREF
(
key
);
Py_XDECREF
(
e
);
Py_XDECREF
(
keys
);
Py_DECREF
(
__dict__
);
return
NULL
;
}
static
struct
PyMethodDef
Per_methods
[]
=
{
{
"__changed__"
,
(
PyCFunction
)
Per___changed__
,
0
,
Per___changed____doc__
},
{
"__save__"
,
(
PyCFunction
)
Per___save__
,
0
,
Per___save____doc__
},
{
"__inform_commit__"
,
(
PyCFunction
)
Per___save__
,
0
,
Per___inform_commit____doc__
},
{
"__inform_abort__"
,
(
PyCFunction
)
Per___inform_abort__
,
0
,
Per___inform_abort____doc__
},
{
"_p___init__"
,
(
PyCFunction
)
Per__p___init__
,
0
,
Per__p___init____doc__
},
{
"__getstate__"
,
(
PyCFunction
)
Per__getstate__
,
0
,
"__getstate__() -- Return the state of the object"
},
{
"__setstate__"
,
(
PyCFunction
)
Per__setstate__
,
0
,
"__setstate__(v) -- Restore the saved state of the object from v"
},
{
NULL
,
NULL
}
/* sentinel */
};
/* ---------- */
static
void
Per_dealloc
(
self
)
Perobject
*
self
;
{
Py_XDECREF
(
self
->
oid
);
Py_XDECREF
(
self
->
jar
);
Py_XDECREF
(
self
->
rtime
);
PyMem_DEL
(
self
);
}
static
PyObject
*
Per_getattr
(
Perobject
*
self
,
PyObject
*
oname
,
char
*
name
)
{
char
*
n
=
name
;
if
(
*
n
++==
'_'
)
if
(
*
n
++==
'p'
&&
*
n
++==
'_'
)
{
switch
(
*
n
++
)
{
case
'o'
:
if
(
*
n
++==
'i'
&&
*
n
++==
'd'
&&
!
*
n
)
{
if
(
self
->
oid
)
{
Py_INCREF
(
self
->
oid
);
return
self
->
oid
;
}
else
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
}
break
;
case
'j'
:
if
(
*
n
++==
'a'
&&
*
n
++==
'r'
&&
!
*
n
)
{
if
(
self
->
jar
)
{
Py_INCREF
(
self
->
jar
);
return
self
->
jar
;
}
else
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
}
break
;
case
'c'
:
if
(
strcmp
(
n
,
"hanged"
)
==
0
)
return
PyInt_FromLong
(
self
->
state
==
CHANGED_STATE
);
case
'r'
:
if
(
strcmp
(
n
,
"ead_time"
)
==
0
)
{
if
(
self
->
rtime
)
{
Py_INCREF
(
self
->
rtime
);
return
self
->
rtime
;
}
else
return
PyFloat_FromDouble
(
0
.
0
);
}
}
}
if
(
!
(
*
name
++==
'_'
&&
*
name
++==
'_'
&&
strcmp
(
name
,
"dict__"
)
==
0
))
{
/* Update state, if necessary */
if
(
self
->
state
==
GHOST_STATE
&&
self
->
jar
)
{
PyObject
*
r
;
self
->
state
=
UPTODATE_STATE
;
UNLESS
(
r
=
callmethod1
(
self
->
jar
,
py_setstate
,(
PyObject
*
)
self
))
{
self
->
state
=
GHOST_STATE
;
return
NULL
;
}
Py_DECREF
(
r
);
}
/* Record access times */
self
->
atime
=
time
(
NULL
);
}
return
Py_FindAttr
((
PyObject
*
)
self
,
oname
);
}
static
PyObject
*
Per_getattro
(
Perobject
*
self
,
PyObject
*
name
)
{
char
*
s
;
UNLESS
(
s
=
PyString_AsString
(
name
))
return
NULL
;
return
Per_getattr
(
self
,
name
,
s
);
}
static
int
Per_setattro
(
Perobject
*
self
,
PyObject
*
oname
,
PyObject
*
v
)
{
char
*
name
;
UNLESS
(
oname
&&
(
name
=
PyString_AsString
(
oname
)))
return
-
1
;
if
(
*
name
==
'_'
&&
name
[
1
]
==
'p'
&&
name
[
2
]
==
'_'
)
{
if
(
name
[
3
]
==
'o'
&&
name
[
4
]
==
'i'
&&
name
[
5
]
==
'd'
&&
!
name
[
6
])
{
ASSIGN
(
self
->
oid
,
v
);
Py_INCREF
(
self
->
oid
);
return
0
;
}
if
(
name
[
3
]
==
'j'
&&
name
[
4
]
==
'a'
&&
name
[
5
]
==
'r'
&&
!
name
[
6
])
{
ASSIGN
(
self
->
jar
,
v
);
Py_INCREF
(
self
->
jar
);
return
0
;
}
if
(
strcmp
(
name
+
3
,
"changed"
)
==
0
)
{
self
->
state
=
PyObject_IsTrue
(
v
);
return
0
;
}
if
(
strcmp
(
name
+
3
,
"read_time"
)
==
0
)
{
ASSIGN
(
self
->
rtime
,
v
);
Py_INCREF
(
self
->
rtime
);
return
0
;
}
}
else
{
PyObject
*
r
;
/* Update state, if necessary */
if
(
self
->
state
==
GHOST_STATE
&&
self
->
jar
)
{
self
->
state
=
UPTODATE_STATE
;
UNLESS
(
r
=
callmethod1
(
self
->
jar
,
py_setstate
,(
PyObject
*
)
self
))
{
self
->
state
=
GHOST_STATE
;
return
-
1
;
}
Py_DECREF
(
r
);
}
/* Record access times */
self
->
atime
=
time
(
NULL
);
if
(
self
->
state
!=
CHANGED_STATE
&&
self
->
jar
)
{
UNLESS
(
r
=
callmethod1
((
PyObject
*
)
self
,
py___changed__
,
py_one
))
return
-
1
;
Py_DECREF
(
r
);
}
}
return
PyEC_SetAttr
((
PyObject
*
)
self
,
oname
,
v
);
}
static
char
Pertype__doc__
[]
=
"Persistent object support mix-in class
\n
"
"
\n
"
"When a persistent object is loaded from a database, the object's
\n
"
"data is not immediately loaded. Loading of the objects data is
\n
"
"defered until an attempt is made to access an attribute of the
\n
"
"object.
\n
"
"
\n
"
"The object also tries to keep track of whether it has changed. It
\n
"
"is easy for this to be done incorrectly. For this reason, methods
\n
"
"of subclasses that change state other than by setting attributes
\n
"
"should: 'self.__changed__(1)' to flag instances as changed.
\n
"
"
\n
"
"Data are not saved automatically. To save an object's state, call
\n
"
"the object's '__save__' method.
\n
"
"
\n
"
"You must not override the object's '__getattr__' and '__setattr__'
\n
"
"methods. If you override the objects '__getstate__' method, then
\n
"
"you must be careful not to include any attributes with names
\n
"
"starting with '_p_' in the state.
\n
"
;
static
PyExtensionClass
Pertype
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"Persistent"
,
/*tp_name*/
sizeof
(
Perobject
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
Per_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
Per_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
Per_setattro
,
/*tp_setattr with object key*/
/* Space for future expansion */
0L
,
0L
,
Pertype__doc__
,
/* Documentation string */
METHOD_CHAIN
(
Per_methods
)
};
/* End of code for Persistent objects */
/* -------------------------------------------------------- */
/* List of methods defined in the module */
static
struct
PyMethodDef
cP_methods
[]
=
{
{
NULL
,
NULL
}
/* sentinel */
};
/* Initialization function for the module (*must* be called initcPersistence) */
static
char
cPersistence_module_documentation
[]
=
""
;
void
initcPersistence
()
{
PyObject
*
m
,
*
d
;
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"cPersistence"
,
cP_methods
,
cPersistence_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
init_strings
();
/* Add some symbolic constants to the module */
d
=
PyModule_GetDict
(
m
);
/* XXXX Add constants here */
PyExtensionClass_Export
(
d
,
"Persistent"
,
Pertype
);
/* Check for errors */
CHECK_FOR_ERRORS
(
"can't initialize module dt"
);
}
src/ZODB/cPersistence.c
0 → 100644
View file @
6f3861e4
/*
$Id: cPersistence.c,v 1.1 1997/02/14 20:24:55 jim Exp $
C Persistence Module
Copyright
Copyright 1996 Digital Creations, L.C., 910 Princess Anne
Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
rights reserved. Copyright in this software is owned by DCLC,
unless otherwise indicated. Permission to use, copy and
distribute this software is hereby granted, provided that the
above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear. Note that
any product, process or technology described in this software
may be the subject of other Intellectual Property rights
reserved by Digital Creations, L.C. and are not licensed
hereunder.
Trademarks
Digital Creations & DCLC, are trademarks of Digital Creations, L.C..
All other trademarks are owned by their respective companies.
No Warranty
The software is provided "as is" without warranty of any kind,
either express or implied, including, but not limited to, the
implied warranties of merchantability, fitness for a particular
purpose, or non-infringement. This software could include
technical inaccuracies or typographical errors. Changes are
periodically made to the software; these changes will be
incorporated in new editions of the software. DCLC may make
improvements and/or changes in this software at any time
without notice.
Limitation Of Liability
In no event will DCLC be liable for direct, indirect, special,
incidental, economic, cover, or consequential damages arising
out of the use of or inability to use this software even if
advised of the possibility of such damages. Some states do not
allow the exclusion or limitation of implied warranties or
limitation of liability for incidental or consequential
damages, so the above limitation or exclusion may not apply to
you.
If you have questions regarding this software,
contact:
Jim Fulton, jim@digicool.com
Digital Creations L.C.
(540) 371-6909
Full description
$Log: cPersistence.c,v $
Revision 1.1 1997/02/14 20:24:55 jim
*** empty log message ***
*/
static
char
*
what_string
=
"$Id: cPersistence.c,v 1.1 1997/02/14 20:24:55 jim Exp $"
;
#include <time.h>
#include "Python.h"
#include "ExtensionClass.h"
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
static
PyObject
*
py_store
,
*
py_oops
,
*
py_keys
,
*
py_setstate
,
*
py___changed__
,
*
py___dict__
,
*
py_one
;
static
void
init_strings
()
{
#define INIT_STRING(S) py_ ## S = PyString_FromString(#S)
INIT_STRING
(
store
);
INIT_STRING
(
oops
);
INIT_STRING
(
keys
);
INIT_STRING
(
setstate
);
INIT_STRING
(
__changed__
);
INIT_STRING
(
__dict__
);
py_one
=
PyInt_FromLong
(
1
);
#undef INIT_STRING
}
static
PyObject
*
callmethod
(
PyObject
*
self
,
PyObject
*
name
)
{
if
(
self
=
PyObject_GetAttr
(
self
,
name
))
ASSIGN
(
self
,
PyObject_CallObject
(
self
,
NULL
));
return
self
;
}
static
PyObject
*
callmethod1
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
arg
)
{
if
((
self
=
PyObject_GetAttr
(
self
,
name
))
&&
(
name
=
PyTuple_New
(
1
)))
{
PyTuple_SET_ITEM
(
name
,
0
,
arg
);
ASSIGN
(
self
,
PyObject_CallObject
(
self
,
name
));
PyTuple_SET_ITEM
(
name
,
0
,
NULL
);
Py_DECREF
(
name
);
}
return
self
;
}
static
PyObject
*
callmethod2
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
arg
,
PyObject
*
arg2
)
{
if
((
self
=
PyObject_GetAttr
(
self
,
name
))
&&
(
name
=
PyTuple_New
(
2
)))
{
PyTuple_SET_ITEM
(
name
,
0
,
arg
);
PyTuple_SET_ITEM
(
name
,
1
,
arg2
);
ASSIGN
(
self
,
PyObject_CallObject
(
self
,
name
));
PyTuple_SET_ITEM
(
name
,
0
,
NULL
);
PyTuple_SET_ITEM
(
name
,
1
,
NULL
);
Py_DECREF
(
name
);
}
return
self
;
}
/* ----------------------------------------------------- */
/* Declarations for objects of type Persistent */
typedef
struct
{
PyObject_HEAD
PyObject
*
oid
;
PyObject
*
jar
;
PyObject
*
rtime
;
time_t
atime
;
int
state
;
#define GHOST_STATE -1
#define UPTODATE_STATE 0
#define CHANGED_STATE 1
}
Perobject
;
staticforward
PyExtensionClass
Pertype
;
staticforward
PyExtensionClass
TPertype
;
/* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- */
static
char
Per___changed____doc__
[]
=
"__changed__([flag]) -- Flag or determine whether an object has changed
\n
"
"
\n
"
"If a value is specified, then it should indicate whether an
\n
"
"object has or has not been changed. If no value is specified,
\n
"
"then the return value will indicate whether the object has
\n
"
"changed.
\n
"
;
static
PyObject
*
changed_args
=
(
PyObject
*
)
Per___changed____doc__
;
static
PyObject
*
Per___changed__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
o
;
if
(
args
)
{
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
o
))
return
NULL
;
if
(
self
->
state
!=
GHOST_STATE
)
self
->
state
=
PyObject_IsTrue
(
o
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
else
return
PyInt_FromLong
(
self
->
state
==
CHANGED_STATE
);
}
static
char
Per___save____doc__
[]
=
"__save__() -- Update the object in a persistent database."
;
static
PyObject
*
Per___save__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
if
(
self
->
oid
&&
self
->
jar
&&
self
->
state
!=
GHOST_STATE
)
return
callmethod1
(
self
->
jar
,
py_store
,(
PyObject
*
)
self
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
char
Per___inform_commit____doc__
[]
=
"__inform_commit__(transaction,start_time) -- Commit object changes"
;
static
char
Per___inform_abort____doc__
[]
=
"__inform_abort__(transaction,start_time) -- Abort object changes"
;
static
PyObject
*
Per___inform_abort__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
transaction
,
*
start_time
;
UNLESS
(
PyArg_Parse
(
args
,
"(OO)"
,
&
transaction
,
&
start_time
))
return
NULL
;
if
(
self
->
oid
&&
self
->
jar
&&
self
->
state
!=
GHOST_STATE
)
{
args
=
callmethod2
(
self
->
jar
,
py_oops
,(
PyObject
*
)
self
,
start_time
);
if
(
args
)
Py_DECREF
(
args
);
else
PyErr_Clear
();
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
char
Per__p___init____doc__
[]
=
"_p___init__(oid,jar) -- Initialize persistence management data"
;
static
PyObject
*
Per__p___init__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
oid
,
*
jar
;
UNLESS
(
PyArg_Parse
(
args
,
"(OO)"
,
&
oid
,
&
jar
))
return
NULL
;
Py_INCREF
(
oid
);
Py_INCREF
(
jar
);
ASSIGN
(
self
->
oid
,
oid
);
ASSIGN
(
self
->
jar
,
jar
);
self
->
state
=
GHOST_STATE
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
Per__getstate__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
__dict__
;
UNLESS
(
PyArg_Parse
(
args
,
""
))
return
NULL
;
/* Update state, if necessary */
if
(
self
->
state
==
GHOST_STATE
&&
self
->
jar
)
{
PyObject
*
r
;
self
->
state
=
UPTODATE_STATE
;
UNLESS
(
r
=
callmethod1
(
self
->
jar
,
py_setstate
,(
PyObject
*
)
self
))
{
self
->
state
=
GHOST_STATE
;
return
NULL
;
}
Py_DECREF
(
r
);
}
UNLESS
(
__dict__
=
PyObject_GetAttr
((
PyObject
*
)
self
,
py___dict__
))
return
NULL
;
if
(
!
PyObject_IsTrue
(
__dict__
))
{
Py_DECREF
(
__dict__
);
__dict__
=
Py_None
;
Py_INCREF
(
__dict__
);
}
return
__dict__
;
}
static
PyObject
*
Per__setstate__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
__dict__
,
*
v
,
*
keys
=
0
,
*
key
=
0
,
*
e
=
0
;
int
l
,
i
;
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
v
))
return
NULL
;
self
->
state
=
UPTODATE_STATE
;
if
(
v
!=
Py_None
)
{
UNLESS
(
__dict__
=
PyObject_GetAttr
((
PyObject
*
)
self
,
py___dict__
))
goto
err
;
UNLESS
(
keys
=
callmethod
(
v
,
py_keys
))
goto
err
;
UNLESS
(
-
1
!=
(
l
=
PyObject_Length
(
keys
)))
goto
err
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
UNLESS_ASSIGN
(
key
,
PySequence_GetItem
(
keys
,
i
))
goto
err
;
UNLESS_ASSIGN
(
e
,
PyObject_GetItem
(
v
,
key
))
goto
err
;
UNLESS
(
-
1
!=
PyObject_SetItem
(
__dict__
,
key
,
e
))
goto
err
;
}
Py_XDECREF
(
key
);
Py_XDECREF
(
e
);
Py_DECREF
(
keys
);
Py_DECREF
(
__dict__
);
}
Py_INCREF
(
Py_None
);
return
Py_None
;
err:
self
->
state
=
GHOST_STATE
;
Py_XDECREF
(
key
);
Py_XDECREF
(
e
);
Py_XDECREF
(
keys
);
Py_DECREF
(
__dict__
);
return
NULL
;
}
static
struct
PyMethodDef
Per_methods
[]
=
{
{
"__changed__"
,
(
PyCFunction
)
Per___changed__
,
0
,
Per___changed____doc__
},
{
"__save__"
,
(
PyCFunction
)
Per___save__
,
0
,
Per___save____doc__
},
{
"__inform_commit__"
,
(
PyCFunction
)
Per___save__
,
0
,
Per___inform_commit____doc__
},
{
"__inform_abort__"
,
(
PyCFunction
)
Per___inform_abort__
,
0
,
Per___inform_abort____doc__
},
{
"_p___init__"
,
(
PyCFunction
)
Per__p___init__
,
0
,
Per__p___init____doc__
},
{
"__getstate__"
,
(
PyCFunction
)
Per__getstate__
,
0
,
"__getstate__() -- Return the state of the object"
},
{
"__setstate__"
,
(
PyCFunction
)
Per__setstate__
,
0
,
"__setstate__(v) -- Restore the saved state of the object from v"
},
{
NULL
,
NULL
}
/* sentinel */
};
/* ---------- */
static
void
Per_dealloc
(
self
)
Perobject
*
self
;
{
Py_XDECREF
(
self
->
oid
);
Py_XDECREF
(
self
->
jar
);
Py_XDECREF
(
self
->
rtime
);
PyMem_DEL
(
self
);
}
static
PyObject
*
Per_getattr
(
Perobject
*
self
,
PyObject
*
oname
,
char
*
name
)
{
char
*
n
=
name
;
if
(
*
n
++==
'_'
)
if
(
*
n
++==
'p'
&&
*
n
++==
'_'
)
{
switch
(
*
n
++
)
{
case
'o'
:
if
(
*
n
++==
'i'
&&
*
n
++==
'd'
&&
!
*
n
)
{
if
(
self
->
oid
)
{
Py_INCREF
(
self
->
oid
);
return
self
->
oid
;
}
else
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
}
break
;
case
'j'
:
if
(
*
n
++==
'a'
&&
*
n
++==
'r'
&&
!
*
n
)
{
if
(
self
->
jar
)
{
Py_INCREF
(
self
->
jar
);
return
self
->
jar
;
}
else
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
}
break
;
case
'c'
:
if
(
strcmp
(
n
,
"hanged"
)
==
0
)
return
PyInt_FromLong
(
self
->
state
==
CHANGED_STATE
);
case
'r'
:
if
(
strcmp
(
n
,
"ead_time"
)
==
0
)
{
if
(
self
->
rtime
)
{
Py_INCREF
(
self
->
rtime
);
return
self
->
rtime
;
}
else
return
PyFloat_FromDouble
(
0
.
0
);
}
}
}
if
(
!
(
*
name
++==
'_'
&&
*
name
++==
'_'
&&
strcmp
(
name
,
"dict__"
)
==
0
))
{
/* Update state, if necessary */
if
(
self
->
state
==
GHOST_STATE
&&
self
->
jar
)
{
PyObject
*
r
;
self
->
state
=
UPTODATE_STATE
;
UNLESS
(
r
=
callmethod1
(
self
->
jar
,
py_setstate
,(
PyObject
*
)
self
))
{
self
->
state
=
GHOST_STATE
;
return
NULL
;
}
Py_DECREF
(
r
);
}
/* Record access times */
self
->
atime
=
time
(
NULL
);
}
return
Py_FindAttr
((
PyObject
*
)
self
,
oname
);
}
static
PyObject
*
Per_getattro
(
Perobject
*
self
,
PyObject
*
name
)
{
char
*
s
;
UNLESS
(
s
=
PyString_AsString
(
name
))
return
NULL
;
return
Per_getattr
(
self
,
name
,
s
);
}
static
int
Per_setattro
(
Perobject
*
self
,
PyObject
*
oname
,
PyObject
*
v
)
{
char
*
name
;
UNLESS
(
oname
&&
(
name
=
PyString_AsString
(
oname
)))
return
-
1
;
if
(
*
name
==
'_'
&&
name
[
1
]
==
'p'
&&
name
[
2
]
==
'_'
)
{
if
(
name
[
3
]
==
'o'
&&
name
[
4
]
==
'i'
&&
name
[
5
]
==
'd'
&&
!
name
[
6
])
{
ASSIGN
(
self
->
oid
,
v
);
Py_INCREF
(
self
->
oid
);
return
0
;
}
if
(
name
[
3
]
==
'j'
&&
name
[
4
]
==
'a'
&&
name
[
5
]
==
'r'
&&
!
name
[
6
])
{
ASSIGN
(
self
->
jar
,
v
);
Py_INCREF
(
self
->
jar
);
return
0
;
}
if
(
strcmp
(
name
+
3
,
"changed"
)
==
0
)
{
self
->
state
=
PyObject_IsTrue
(
v
);
return
0
;
}
if
(
strcmp
(
name
+
3
,
"read_time"
)
==
0
)
{
ASSIGN
(
self
->
rtime
,
v
);
Py_INCREF
(
self
->
rtime
);
return
0
;
}
}
else
{
PyObject
*
r
;
/* Update state, if necessary */
if
(
self
->
state
==
GHOST_STATE
&&
self
->
jar
)
{
self
->
state
=
UPTODATE_STATE
;
UNLESS
(
r
=
callmethod1
(
self
->
jar
,
py_setstate
,(
PyObject
*
)
self
))
{
self
->
state
=
GHOST_STATE
;
return
-
1
;
}
Py_DECREF
(
r
);
}
/* Record access times */
self
->
atime
=
time
(
NULL
);
if
(
self
->
state
!=
CHANGED_STATE
&&
self
->
jar
)
{
UNLESS
(
r
=
callmethod1
((
PyObject
*
)
self
,
py___changed__
,
py_one
))
return
-
1
;
Py_DECREF
(
r
);
}
}
return
PyEC_SetAttr
((
PyObject
*
)
self
,
oname
,
v
);
}
static
char
Pertype__doc__
[]
=
"Persistent object support mix-in class
\n
"
"
\n
"
"When a persistent object is loaded from a database, the object's
\n
"
"data is not immediately loaded. Loading of the objects data is
\n
"
"defered until an attempt is made to access an attribute of the
\n
"
"object.
\n
"
"
\n
"
"The object also tries to keep track of whether it has changed. It
\n
"
"is easy for this to be done incorrectly. For this reason, methods
\n
"
"of subclasses that change state other than by setting attributes
\n
"
"should: 'self.__changed__(1)' to flag instances as changed.
\n
"
"
\n
"
"Data are not saved automatically. To save an object's state, call
\n
"
"the object's '__save__' method.
\n
"
"
\n
"
"You must not override the object's '__getattr__' and '__setattr__'
\n
"
"methods. If you override the objects '__getstate__' method, then
\n
"
"you must be careful not to include any attributes with names
\n
"
"starting with '_p_' in the state.
\n
"
;
static
PyExtensionClass
Pertype
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"Persistent"
,
/*tp_name*/
sizeof
(
Perobject
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
Per_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
Per_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
Per_setattro
,
/*tp_setattr with object key*/
/* Space for future expansion */
0L
,
0L
,
Pertype__doc__
,
/* Documentation string */
METHOD_CHAIN
(
Per_methods
)
};
/* End of code for Persistent objects */
/* -------------------------------------------------------- */
/* List of methods defined in the module */
static
struct
PyMethodDef
cP_methods
[]
=
{
{
NULL
,
NULL
}
/* sentinel */
};
/* Initialization function for the module (*must* be called initcPersistence) */
static
char
cPersistence_module_documentation
[]
=
""
;
void
initcPersistence
()
{
PyObject
*
m
,
*
d
;
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"cPersistence"
,
cP_methods
,
cPersistence_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
init_strings
();
/* Add some symbolic constants to the module */
d
=
PyModule_GetDict
(
m
);
/* XXXX Add constants here */
PyExtensionClass_Export
(
d
,
"Persistent"
,
Pertype
);
/* Check for errors */
CHECK_FOR_ERRORS
(
"can't initialize module dt"
);
}
src/persistent/cPersistence.c
0 → 100644
View file @
6f3861e4
/*
$Id: cPersistence.c,v 1.1 1997/02/14 20:24:55 jim Exp $
C Persistence Module
Copyright
Copyright 1996 Digital Creations, L.C., 910 Princess Anne
Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All
rights reserved. Copyright in this software is owned by DCLC,
unless otherwise indicated. Permission to use, copy and
distribute this software is hereby granted, provided that the
above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear. Note that
any product, process or technology described in this software
may be the subject of other Intellectual Property rights
reserved by Digital Creations, L.C. and are not licensed
hereunder.
Trademarks
Digital Creations & DCLC, are trademarks of Digital Creations, L.C..
All other trademarks are owned by their respective companies.
No Warranty
The software is provided "as is" without warranty of any kind,
either express or implied, including, but not limited to, the
implied warranties of merchantability, fitness for a particular
purpose, or non-infringement. This software could include
technical inaccuracies or typographical errors. Changes are
periodically made to the software; these changes will be
incorporated in new editions of the software. DCLC may make
improvements and/or changes in this software at any time
without notice.
Limitation Of Liability
In no event will DCLC be liable for direct, indirect, special,
incidental, economic, cover, or consequential damages arising
out of the use of or inability to use this software even if
advised of the possibility of such damages. Some states do not
allow the exclusion or limitation of implied warranties or
limitation of liability for incidental or consequential
damages, so the above limitation or exclusion may not apply to
you.
If you have questions regarding this software,
contact:
Jim Fulton, jim@digicool.com
Digital Creations L.C.
(540) 371-6909
Full description
$Log: cPersistence.c,v $
Revision 1.1 1997/02/14 20:24:55 jim
*** empty log message ***
*/
static
char
*
what_string
=
"$Id: cPersistence.c,v 1.1 1997/02/14 20:24:55 jim Exp $"
;
#include <time.h>
#include "Python.h"
#include "ExtensionClass.h"
#define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;}
#define UNLESS(E) if(!(E))
#define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V)
static
PyObject
*
py_store
,
*
py_oops
,
*
py_keys
,
*
py_setstate
,
*
py___changed__
,
*
py___dict__
,
*
py_one
;
static
void
init_strings
()
{
#define INIT_STRING(S) py_ ## S = PyString_FromString(#S)
INIT_STRING
(
store
);
INIT_STRING
(
oops
);
INIT_STRING
(
keys
);
INIT_STRING
(
setstate
);
INIT_STRING
(
__changed__
);
INIT_STRING
(
__dict__
);
py_one
=
PyInt_FromLong
(
1
);
#undef INIT_STRING
}
static
PyObject
*
callmethod
(
PyObject
*
self
,
PyObject
*
name
)
{
if
(
self
=
PyObject_GetAttr
(
self
,
name
))
ASSIGN
(
self
,
PyObject_CallObject
(
self
,
NULL
));
return
self
;
}
static
PyObject
*
callmethod1
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
arg
)
{
if
((
self
=
PyObject_GetAttr
(
self
,
name
))
&&
(
name
=
PyTuple_New
(
1
)))
{
PyTuple_SET_ITEM
(
name
,
0
,
arg
);
ASSIGN
(
self
,
PyObject_CallObject
(
self
,
name
));
PyTuple_SET_ITEM
(
name
,
0
,
NULL
);
Py_DECREF
(
name
);
}
return
self
;
}
static
PyObject
*
callmethod2
(
PyObject
*
self
,
PyObject
*
name
,
PyObject
*
arg
,
PyObject
*
arg2
)
{
if
((
self
=
PyObject_GetAttr
(
self
,
name
))
&&
(
name
=
PyTuple_New
(
2
)))
{
PyTuple_SET_ITEM
(
name
,
0
,
arg
);
PyTuple_SET_ITEM
(
name
,
1
,
arg2
);
ASSIGN
(
self
,
PyObject_CallObject
(
self
,
name
));
PyTuple_SET_ITEM
(
name
,
0
,
NULL
);
PyTuple_SET_ITEM
(
name
,
1
,
NULL
);
Py_DECREF
(
name
);
}
return
self
;
}
/* ----------------------------------------------------- */
/* Declarations for objects of type Persistent */
typedef
struct
{
PyObject_HEAD
PyObject
*
oid
;
PyObject
*
jar
;
PyObject
*
rtime
;
time_t
atime
;
int
state
;
#define GHOST_STATE -1
#define UPTODATE_STATE 0
#define CHANGED_STATE 1
}
Perobject
;
staticforward
PyExtensionClass
Pertype
;
staticforward
PyExtensionClass
TPertype
;
/* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- */
static
char
Per___changed____doc__
[]
=
"__changed__([flag]) -- Flag or determine whether an object has changed
\n
"
"
\n
"
"If a value is specified, then it should indicate whether an
\n
"
"object has or has not been changed. If no value is specified,
\n
"
"then the return value will indicate whether the object has
\n
"
"changed.
\n
"
;
static
PyObject
*
changed_args
=
(
PyObject
*
)
Per___changed____doc__
;
static
PyObject
*
Per___changed__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
o
;
if
(
args
)
{
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
o
))
return
NULL
;
if
(
self
->
state
!=
GHOST_STATE
)
self
->
state
=
PyObject_IsTrue
(
o
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
else
return
PyInt_FromLong
(
self
->
state
==
CHANGED_STATE
);
}
static
char
Per___save____doc__
[]
=
"__save__() -- Update the object in a persistent database."
;
static
PyObject
*
Per___save__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
if
(
self
->
oid
&&
self
->
jar
&&
self
->
state
!=
GHOST_STATE
)
return
callmethod1
(
self
->
jar
,
py_store
,(
PyObject
*
)
self
);
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
char
Per___inform_commit____doc__
[]
=
"__inform_commit__(transaction,start_time) -- Commit object changes"
;
static
char
Per___inform_abort____doc__
[]
=
"__inform_abort__(transaction,start_time) -- Abort object changes"
;
static
PyObject
*
Per___inform_abort__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
transaction
,
*
start_time
;
UNLESS
(
PyArg_Parse
(
args
,
"(OO)"
,
&
transaction
,
&
start_time
))
return
NULL
;
if
(
self
->
oid
&&
self
->
jar
&&
self
->
state
!=
GHOST_STATE
)
{
args
=
callmethod2
(
self
->
jar
,
py_oops
,(
PyObject
*
)
self
,
start_time
);
if
(
args
)
Py_DECREF
(
args
);
else
PyErr_Clear
();
}
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
char
Per__p___init____doc__
[]
=
"_p___init__(oid,jar) -- Initialize persistence management data"
;
static
PyObject
*
Per__p___init__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
oid
,
*
jar
;
UNLESS
(
PyArg_Parse
(
args
,
"(OO)"
,
&
oid
,
&
jar
))
return
NULL
;
Py_INCREF
(
oid
);
Py_INCREF
(
jar
);
ASSIGN
(
self
->
oid
,
oid
);
ASSIGN
(
self
->
jar
,
jar
);
self
->
state
=
GHOST_STATE
;
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
Per__getstate__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
__dict__
;
UNLESS
(
PyArg_Parse
(
args
,
""
))
return
NULL
;
/* Update state, if necessary */
if
(
self
->
state
==
GHOST_STATE
&&
self
->
jar
)
{
PyObject
*
r
;
self
->
state
=
UPTODATE_STATE
;
UNLESS
(
r
=
callmethod1
(
self
->
jar
,
py_setstate
,(
PyObject
*
)
self
))
{
self
->
state
=
GHOST_STATE
;
return
NULL
;
}
Py_DECREF
(
r
);
}
UNLESS
(
__dict__
=
PyObject_GetAttr
((
PyObject
*
)
self
,
py___dict__
))
return
NULL
;
if
(
!
PyObject_IsTrue
(
__dict__
))
{
Py_DECREF
(
__dict__
);
__dict__
=
Py_None
;
Py_INCREF
(
__dict__
);
}
return
__dict__
;
}
static
PyObject
*
Per__setstate__
(
self
,
args
)
Perobject
*
self
;
PyObject
*
args
;
{
PyObject
*
__dict__
,
*
v
,
*
keys
=
0
,
*
key
=
0
,
*
e
=
0
;
int
l
,
i
;
UNLESS
(
PyArg_Parse
(
args
,
"O"
,
&
v
))
return
NULL
;
self
->
state
=
UPTODATE_STATE
;
if
(
v
!=
Py_None
)
{
UNLESS
(
__dict__
=
PyObject_GetAttr
((
PyObject
*
)
self
,
py___dict__
))
goto
err
;
UNLESS
(
keys
=
callmethod
(
v
,
py_keys
))
goto
err
;
UNLESS
(
-
1
!=
(
l
=
PyObject_Length
(
keys
)))
goto
err
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
UNLESS_ASSIGN
(
key
,
PySequence_GetItem
(
keys
,
i
))
goto
err
;
UNLESS_ASSIGN
(
e
,
PyObject_GetItem
(
v
,
key
))
goto
err
;
UNLESS
(
-
1
!=
PyObject_SetItem
(
__dict__
,
key
,
e
))
goto
err
;
}
Py_XDECREF
(
key
);
Py_XDECREF
(
e
);
Py_DECREF
(
keys
);
Py_DECREF
(
__dict__
);
}
Py_INCREF
(
Py_None
);
return
Py_None
;
err:
self
->
state
=
GHOST_STATE
;
Py_XDECREF
(
key
);
Py_XDECREF
(
e
);
Py_XDECREF
(
keys
);
Py_DECREF
(
__dict__
);
return
NULL
;
}
static
struct
PyMethodDef
Per_methods
[]
=
{
{
"__changed__"
,
(
PyCFunction
)
Per___changed__
,
0
,
Per___changed____doc__
},
{
"__save__"
,
(
PyCFunction
)
Per___save__
,
0
,
Per___save____doc__
},
{
"__inform_commit__"
,
(
PyCFunction
)
Per___save__
,
0
,
Per___inform_commit____doc__
},
{
"__inform_abort__"
,
(
PyCFunction
)
Per___inform_abort__
,
0
,
Per___inform_abort____doc__
},
{
"_p___init__"
,
(
PyCFunction
)
Per__p___init__
,
0
,
Per__p___init____doc__
},
{
"__getstate__"
,
(
PyCFunction
)
Per__getstate__
,
0
,
"__getstate__() -- Return the state of the object"
},
{
"__setstate__"
,
(
PyCFunction
)
Per__setstate__
,
0
,
"__setstate__(v) -- Restore the saved state of the object from v"
},
{
NULL
,
NULL
}
/* sentinel */
};
/* ---------- */
static
void
Per_dealloc
(
self
)
Perobject
*
self
;
{
Py_XDECREF
(
self
->
oid
);
Py_XDECREF
(
self
->
jar
);
Py_XDECREF
(
self
->
rtime
);
PyMem_DEL
(
self
);
}
static
PyObject
*
Per_getattr
(
Perobject
*
self
,
PyObject
*
oname
,
char
*
name
)
{
char
*
n
=
name
;
if
(
*
n
++==
'_'
)
if
(
*
n
++==
'p'
&&
*
n
++==
'_'
)
{
switch
(
*
n
++
)
{
case
'o'
:
if
(
*
n
++==
'i'
&&
*
n
++==
'd'
&&
!
*
n
)
{
if
(
self
->
oid
)
{
Py_INCREF
(
self
->
oid
);
return
self
->
oid
;
}
else
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
}
break
;
case
'j'
:
if
(
*
n
++==
'a'
&&
*
n
++==
'r'
&&
!
*
n
)
{
if
(
self
->
jar
)
{
Py_INCREF
(
self
->
jar
);
return
self
->
jar
;
}
else
{
Py_INCREF
(
Py_None
);
return
Py_None
;
}
}
break
;
case
'c'
:
if
(
strcmp
(
n
,
"hanged"
)
==
0
)
return
PyInt_FromLong
(
self
->
state
==
CHANGED_STATE
);
case
'r'
:
if
(
strcmp
(
n
,
"ead_time"
)
==
0
)
{
if
(
self
->
rtime
)
{
Py_INCREF
(
self
->
rtime
);
return
self
->
rtime
;
}
else
return
PyFloat_FromDouble
(
0
.
0
);
}
}
}
if
(
!
(
*
name
++==
'_'
&&
*
name
++==
'_'
&&
strcmp
(
name
,
"dict__"
)
==
0
))
{
/* Update state, if necessary */
if
(
self
->
state
==
GHOST_STATE
&&
self
->
jar
)
{
PyObject
*
r
;
self
->
state
=
UPTODATE_STATE
;
UNLESS
(
r
=
callmethod1
(
self
->
jar
,
py_setstate
,(
PyObject
*
)
self
))
{
self
->
state
=
GHOST_STATE
;
return
NULL
;
}
Py_DECREF
(
r
);
}
/* Record access times */
self
->
atime
=
time
(
NULL
);
}
return
Py_FindAttr
((
PyObject
*
)
self
,
oname
);
}
static
PyObject
*
Per_getattro
(
Perobject
*
self
,
PyObject
*
name
)
{
char
*
s
;
UNLESS
(
s
=
PyString_AsString
(
name
))
return
NULL
;
return
Per_getattr
(
self
,
name
,
s
);
}
static
int
Per_setattro
(
Perobject
*
self
,
PyObject
*
oname
,
PyObject
*
v
)
{
char
*
name
;
UNLESS
(
oname
&&
(
name
=
PyString_AsString
(
oname
)))
return
-
1
;
if
(
*
name
==
'_'
&&
name
[
1
]
==
'p'
&&
name
[
2
]
==
'_'
)
{
if
(
name
[
3
]
==
'o'
&&
name
[
4
]
==
'i'
&&
name
[
5
]
==
'd'
&&
!
name
[
6
])
{
ASSIGN
(
self
->
oid
,
v
);
Py_INCREF
(
self
->
oid
);
return
0
;
}
if
(
name
[
3
]
==
'j'
&&
name
[
4
]
==
'a'
&&
name
[
5
]
==
'r'
&&
!
name
[
6
])
{
ASSIGN
(
self
->
jar
,
v
);
Py_INCREF
(
self
->
jar
);
return
0
;
}
if
(
strcmp
(
name
+
3
,
"changed"
)
==
0
)
{
self
->
state
=
PyObject_IsTrue
(
v
);
return
0
;
}
if
(
strcmp
(
name
+
3
,
"read_time"
)
==
0
)
{
ASSIGN
(
self
->
rtime
,
v
);
Py_INCREF
(
self
->
rtime
);
return
0
;
}
}
else
{
PyObject
*
r
;
/* Update state, if necessary */
if
(
self
->
state
==
GHOST_STATE
&&
self
->
jar
)
{
self
->
state
=
UPTODATE_STATE
;
UNLESS
(
r
=
callmethod1
(
self
->
jar
,
py_setstate
,(
PyObject
*
)
self
))
{
self
->
state
=
GHOST_STATE
;
return
-
1
;
}
Py_DECREF
(
r
);
}
/* Record access times */
self
->
atime
=
time
(
NULL
);
if
(
self
->
state
!=
CHANGED_STATE
&&
self
->
jar
)
{
UNLESS
(
r
=
callmethod1
((
PyObject
*
)
self
,
py___changed__
,
py_one
))
return
-
1
;
Py_DECREF
(
r
);
}
}
return
PyEC_SetAttr
((
PyObject
*
)
self
,
oname
,
v
);
}
static
char
Pertype__doc__
[]
=
"Persistent object support mix-in class
\n
"
"
\n
"
"When a persistent object is loaded from a database, the object's
\n
"
"data is not immediately loaded. Loading of the objects data is
\n
"
"defered until an attempt is made to access an attribute of the
\n
"
"object.
\n
"
"
\n
"
"The object also tries to keep track of whether it has changed. It
\n
"
"is easy for this to be done incorrectly. For this reason, methods
\n
"
"of subclasses that change state other than by setting attributes
\n
"
"should: 'self.__changed__(1)' to flag instances as changed.
\n
"
"
\n
"
"Data are not saved automatically. To save an object's state, call
\n
"
"the object's '__save__' method.
\n
"
"
\n
"
"You must not override the object's '__getattr__' and '__setattr__'
\n
"
"methods. If you override the objects '__getstate__' method, then
\n
"
"you must be careful not to include any attributes with names
\n
"
"starting with '_p_' in the state.
\n
"
;
static
PyExtensionClass
Pertype
=
{
PyObject_HEAD_INIT
(
NULL
)
0
,
/*ob_size*/
"Persistent"
,
/*tp_name*/
sizeof
(
Perobject
),
/*tp_basicsize*/
0
,
/*tp_itemsize*/
/* methods */
(
destructor
)
Per_dealloc
,
/*tp_dealloc*/
(
printfunc
)
0
,
/*tp_print*/
(
getattrfunc
)
0
,
/*tp_getattr*/
(
setattrfunc
)
0
,
/*tp_setattr*/
(
cmpfunc
)
0
,
/*tp_compare*/
(
reprfunc
)
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
(
hashfunc
)
0
,
/*tp_hash*/
(
ternaryfunc
)
0
,
/*tp_call*/
(
reprfunc
)
0
,
/*tp_str*/
(
getattrofunc
)
Per_getattro
,
/*tp_getattr with object key*/
(
setattrofunc
)
Per_setattro
,
/*tp_setattr with object key*/
/* Space for future expansion */
0L
,
0L
,
Pertype__doc__
,
/* Documentation string */
METHOD_CHAIN
(
Per_methods
)
};
/* End of code for Persistent objects */
/* -------------------------------------------------------- */
/* List of methods defined in the module */
static
struct
PyMethodDef
cP_methods
[]
=
{
{
NULL
,
NULL
}
/* sentinel */
};
/* Initialization function for the module (*must* be called initcPersistence) */
static
char
cPersistence_module_documentation
[]
=
""
;
void
initcPersistence
()
{
PyObject
*
m
,
*
d
;
/* Create the module and add the functions */
m
=
Py_InitModule4
(
"cPersistence"
,
cP_methods
,
cPersistence_module_documentation
,
(
PyObject
*
)
NULL
,
PYTHON_API_VERSION
);
init_strings
();
/* Add some symbolic constants to the module */
d
=
PyModule_GetDict
(
m
);
/* XXXX Add constants here */
PyExtensionClass_Export
(
d
,
"Persistent"
,
Pertype
);
/* Check for errors */
CHECK_FOR_ERRORS
(
"can't initialize module dt"
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment