MSI read support in msilib?

F

Floris Bruynooghe

Hi

The introduction from the msilib documentation in python 2.5 claims it
supports reading an msi. However on the Record class there is only a
GetFieldCount() method and some Set*() methods. I was expecting to
see GetString() and GetInteger() methods to be able to read the
values.

Maybe I'm missing something? Is there an other way to read the data
of a record?

Regards
Floris
 
M

Martin v. Löwis

The introduction from the msilib documentation in python 2.5 claims it
supports reading an msi. However on the Record class there is only a
GetFieldCount() method and some Set*() methods. I was expecting to
see GetString() and GetInteger() methods to be able to read the
values.

Maybe I'm missing something?

I think you are right - there is indeed stuff missing; few people have
noticed so far.

Regards,
Martin
 
F

Floris Bruynooghe

I think you are right - there is indeed stuff missing; few people have
noticed so far.

Ok, below is the patch I made and tested. It is still missing a
wrapper for MsiRecordReadStream() but I didn't need that right
now ;-). It is a patch against Python 2.5.1 (ignore revision numbers
as they're not from svn.python.org).

Let me know if this is any good or comments etc. Would it be good to
include in python? Maybe I should create the diff against the trunk
and file a patch report?

Regards
Floris


Index: _msi.c
===================================================================
--- _msi.c (revision 2547)
+++ _msi.c (working copy)
@@ -339,6 +339,53 @@
}

static PyObject*
+record_getinteger(msiobj* record, PyObject* args)
+{
+ unsigned int field;
+ int status;
+
+ if (!PyArg_ParseTuple(args, "I:GetInteger", &field))
+ return NULL;
+
+ status = MsiRecordGetInteger(record->h, field);
+ if (status == MSI_NULL_INTEGER){
+ PyErr_SetString(MSIError, "could not convert record field to
integer");
+ return NULL;
+ }
+ return PyInt_FromLong((long) status);
+}
+
+static PyObject*
+record_getstring(msiobj* record, PyObject* args)
+{
+ unsigned int field;
+ unsigned int status;
+ char buf[2000];
+ char *res = buf;
+ int malloc_flag = 0;
+ DWORD size = sizeof(buf);
+ PyObject* string;
+
+ if (!PyArg_ParseTuple(args, "I:GetString", &field))
+ return NULL;
+
+ status = MsiRecordGetString(record->h, field, res, &size);
+ if (status == ERROR_MORE_DATA) {
+ res = (char*) malloc(size + 1);
+ if (res == NULL)
+ return PyErr_NoMemory();
+ status = MsiRecordGetString(record->h, field, res, &size);
+ }
+
+ if (status != ERROR_SUCCESS)
+ return msierror((int) status);
+ string = PyString_FromString(res);
+ if (buf != res)
+ free(res);
+ return string;
+}
+
+static PyObject*
record_cleardata(msiobj* record, PyObject *args)
{
int status = MsiRecordClearData(record->h);
@@ -405,6 +452,10 @@
static PyMethodDef record_methods[] = {
{ "GetFieldCount", (PyCFunction)record_getfieldcount,
METH_NOARGS,
PyDoc_STR("GetFieldCount() -> int\nWraps MsiRecordGetFieldCount")},
+ { "GetInteger", (PyCFunction)record_getinteger, METH_VARARGS,
+ PyDoc_STR("GetInteger(field) -> int\nWraps
MsiRecordGetInteger")},
+ { "GetString", (PyCFunction)record_getstring, METH_VARARGS,
+ PyDoc_STR("GetString(field) -> string\nWraps
MsiRecordGetString")},
{ "SetString", (PyCFunction)record_setstring, METH_VARARGS,
PyDoc_STR("SetString(field,str) -> None\nWraps
MsiRecordSetString")},
{ "SetStream", (PyCFunction)record_setstream, METH_VARARGS,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top