This commit is contained in:
Michael Davidsaver
2013-03-24 22:10:53 -04:00
parent f58ba8dccb
commit 0f4b62e45d
8 changed files with 150 additions and 10 deletions

View File

@ -20,7 +20,7 @@ static int pyField_Init(pyField *self, PyObject *args, PyObject *kws)
{
const char *pvname;
if(PyArg_ParseTuple(args, "s", &pvname))
if(!PyArg_ParseTuple(args, "s", &pvname))
return -1;
if(dbNameToAddr(pvname, &self->addr)) {
@ -157,7 +157,7 @@ static PyMethodDef pyField_methods[] = {
"Return Names (\"record\",\"field\")"},
{"fieldinfo", (PyCFunction)pyField_fldinfo, METH_NOARGS,
"Field type info\nReturn (type, size, #elements"},
{"getval", (PyCFunction)pyField_getval, METH_VARARGS,
{"getval", (PyCFunction)pyField_getval, METH_NOARGS,
"Returns scalar version of field value"},
{"putval", (PyCFunction)pyField_putval, METH_VARARGS,
"Sets field value from a scalar"},
@ -168,13 +168,13 @@ static PyMethodDef pyField_methods[] = {
static PyTypeObject pyField_type = {
PyObject_HEAD_INIT(NULL)
0,
"_dbapi.Field",
"_dbapi._Field",
sizeof(pyField),
};
int pyField_prepare(void)
{
pyField_type.tp_flags = Py_TPFLAGS_DEFAULT;
pyField_type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
pyField_type.tp_methods = pyField_methods;
pyField_type.tp_init = (initproc)pyField_Init;
@ -188,5 +188,5 @@ void pyField_setup(PyObject *module)
{
PyObject *typeobj=(PyObject*)&pyField_type;
Py_INCREF(typeobj);
PyModule_AddObject(module, "Field", (PyObject*)&pyField_type);
PyModule_AddObject(module, "_Field", (PyObject*)&pyField_type);
}

View File

@ -20,7 +20,6 @@ typedef struct {
static int pyRecord_Init(pyRecord *self, PyObject *args, PyObject *kws)
{
const char *recname;
if(!PyArg_ParseTuple(args, "s", &recname))
return -1;
@ -136,14 +135,14 @@ static PyMethodDef pyRecord_methods[] = {
static PyTypeObject pyRecord_type = {
PyObject_HEAD_INIT(NULL)
0,
"_dbapi.Record",
"_dbapi._Record",
sizeof(pyRecord),
};
int pyRecord_prepare(void)
{
pyRecord_type.tp_flags = Py_TPFLAGS_DEFAULT;
pyRecord_type.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
pyRecord_type.tp_methods = pyRecord_methods;
pyRecord_type.tp_init = (initproc)pyRecord_Init;
@ -157,5 +156,5 @@ void pyRecord_setup(PyObject *module)
{
PyObject *typeobj=(PyObject*)&pyRecord_type;
Py_INCREF(typeobj);
PyModule_AddObject(module, "Field", (PyObject*)&pyRecord_type);
PyModule_AddObject(module, "_Record", (PyObject*)&pyRecord_type);
}

View File

@ -0,0 +1,8 @@
try:
import _dbapi
except ImportError:
import _nullapi as _dbapi
__all__ = ['verinfo']
from _dbapi import verinfo

69
python/devsup/_nullapi.py Normal file
View File

@ -0,0 +1,69 @@
def verinfo():
"""(VER, REV, MOD, PATH, "site") = verinfo()
Query EPICS version information
"""
return (0,0,0,0.'invalid')
class Record(object):
"""Handle for record operations
r = Record("rec:name")
"""
def __init__(self, rec):
pass
def name(self):
"""Record name
"""
def info(self, key):
"""info(key)
info(key, default)
Lookup record info tag. If no default
is provided then an exception is raised
if the info key does not exist.
"""
def infos(self):
"""Return a dictionary of all info tags
for this record
"""
def scan(self, sync=False):
"""scan(sync=False)
Scan this record. If sync is False then a
scan request is queued. If sync is True then the record
is scannined immidately on the current thread.
"""
def Field(object):
"""Handle for field operations
f = Field("rec:name.HOPR")
"""
def __init__(self, fld):
pass
def name(self):
"""("rec", "FLD") = name()
"""
def fieldinfo(self):
"""(type, size, #elements) = fieldinfo()
Type is DBF type code
size is number of bytes to start a single element
#elements is the maximum number of elements the field can hold
"""
def getval(self):
"""Fetch the current field value as a scalar.
Returns Int, Float, or str
"""
def putval(self, val):
"""Update the field value
Must be an Int, Float or str
"""

54
python/devsup/db.py Normal file
View File

@ -0,0 +1,54 @@
try:
import _dbapi
except ImportError:
import _nullapi as _dbapi
from _dbapi import _Field, _Record
_rec_cache = {}
__all__ = [
'Record',
'Field',
]
def getRecord(name):
try:
return _rec_cache[name]
except KeyError:
rec = Record(name)
_rec_cache[name] = rec
return rec
class Record(_Record):
def __init__(self, *args, **kws):
super(Record, self).__init__(*args, **kws)
self._fld_cache = {}
def field(self, name):
"""Lookup field in this record
fld = rec.field('HOPR')
"""
try:
return self._fld_cache[name]
except KeyError:
fld = Field("%s.%s"%(self.name(), name))
self._fld_cache[name] = fld
return fld
def __repr__(self):
return 'Record("%s")'%self.name()
class Field(_Field):
@property
def record(self):
"""Fetch the record associated with this field
"""
try:
return self._record
except AttributeError:
rec, _ = self.name()
self._record = getRecord(rec)
return self._record
def __repr__(self):
return 'Field("%s.%s")'%self.name()

View File

@ -1,4 +1,7 @@
try:
import _dbapi
except ImportError:
import _nullapi as _dbapi
from _dbapi import _hooks, _hooktable
__all__ = [

View File

@ -9,5 +9,11 @@ evalPy "import sys"
evalPy "print sys.path"
evalPy "import devsup.hooks"
evalPy "devsup.hooks.debugHooks()"
evalPy "import devsup.db"
dbLoadRecords("test.db","")
iocInit
evalPy "print devsup.db.Record('test:rec')"
evalPy "print devsup.db.Record('does:not:exist')"

1
test.db Normal file
View File

@ -0,0 +1 @@
record(ai, "test:rec") {}