|
![]() |
![]() |
version 2003
PA_GetPackedRecord (tNum; packRec) → long
Parameter | Type | Description | |
tNum | short | → | Table number |
packRec | void * | ← | Buffer to store the record data |
Function result | long | ← | Buffer size |
Description
The routine
PA_GetPackedRecord
fills the memory block pointed to by
packRec
with data that contains the concatenation of all the fields of the current record of the table whose number is passed in
tNum
, and returns its size. If there is no current record when the call is made, the routine returns 0. If
packRec
is nil, the routine returns the actual size of the record, so the developer can allocate a buffer of the correct size before filling it.
First, the 4D Plug-in usually calls the routine passing
packRec
to nil, then allocates the buffer, and finally recalls the routine with the buffer.
NOTE
4th Dimension uses a private data format for concatenating fields into one block. It is impossible for the 4D Plug-in to extract one particular Field from this block. The 4D Plug-in should never modify this data.
4th Dimension takes care of the data from one platform to another, and the 4D Plug-in can transparently get a packed record on a platform and use it on another.
The buffer returned in
packRec
can be reused with the routine
PA_SetPackedRecord
.
For example, if the 4D plug-in requires record duplication, this can be accomplished by first making the desired record the current record for the table and calling
PA_GetPackedRecord
to get a copy of all the record's fields. Once the packed record has been copied, the 4D plug-in should call
PA_CreateRecord
and then
PA_SetPackedRecord
to fill out all the fields of the new record. Finally, the 4D plug-in should save the new record by calling
PA_SaveRecord
and dispose of the buffer.
This method can also be used to export and import records from one database to another provided the source and destination files have an identical table definition. The use of the routines
PA_GetPackedRecord
and
PA_SetPackedRecord
however are not restricted to the duplication or export/import of records.
PA_SetPackedRecord
can be called on existing records in order to insure data synchronization between databases, provided the source and destination files have an identical table definition.
If new records are created, it is up to the 4D plug-in to handle the unity of field(s) if necessary.
If the 4D plug-in sends or receives record data returned by
PA_GetPackedRecord
over a phone line, a software or hardware protocol should be used, such as XOn/XOff, as record data may contain ASCII codes which interferes with a standard protocol.
Examples
(1) Duplicate the current record.
short DuplicateRecord (short tNum)
{
long size = 0;
char *buffer;
// Get the size of the packed record
size = PA_GetPackedRecord(tNum, 0L);
// Continue only if no error occurred and if there were a current record
if( (PA_GetLastError() == eER_NoErr) && (size > 0) )
{
// Allocate the buffer
buffer = malloc(size);
// Fill it
if(buffer)
{
size = PA_GetPackedRecord(tNum, buffer);
// Create and fill a new record
if(PA_GetLastError() == eER_NoErr)
{
PA_CreateRecord(tNum);
PA_SetPackedRecord(tNum, buffer, size);
PA_SaveRecord(tNum);
}
}
}
return PA_GetLastError();
}
(2) BLOB and unBLOB a record as routines given to the 4D programer. The documentation of the Plug-in will look like this:
<<
To BLOB the current record of a table, use:
$error:=myplug_BlobRecord(tNum;blob)
where
tNum
is an integer (the number of the table) and
blob
is a BLOB in witch you want to store the record. $error is a long integer containing an error code, 0 = no error.
To unBLOB a record previously BLOBed with
myplug_BlobRecord
, use:
$error:=myplug_UnblobRecord(tNum;blob)
where
tNum
is an integer (the number of the table) and
blob
is a valid BLOB containing the record. The Plug-in does not save the record for you.
>>
void PluginMain( long selector, PA_PluginParameters params )
{
switch ( selector )
{
case kInitPlugin :
// enter initialization code here if needed
break;
case kDeinitPlugin :
// enter de-initialization code here if needed
break;
case kBLOB_RECORD :
BlobTheRecord(params);
break;
case kUNBLOB_RECORD :
UnblobTheRecord(params);
break;
case 3 :
// enter code for third command here
break;
.
.
.
}
} // PluginMain
// Declared for the 4D Developer as expecting:
// - a short (table number),
// - a BLOB
// - and return a long (error)
void BlobTheRecord (PA_PluginParameters params)
{
long size = 0;
char *buffer;
short tNum = 0;
short err = 0;
// Get the table number (first parameter)
tNum = PA_GetShortParameter(params, 1);
// Get the size of the packed record
size = PA_GetPackedRecord(tNum, 0L);
// error check
err = PA_GetLastError();
if( (!err) && (size > 0) )
{
buffer = malloc(size);
if(buffer)
{
size = PA_GetPackedRecord(tNum, buffer);
if( (!err) && (size > 0) )
{
// The BLOB to fill is the second parameter
PA_SetBlobParameter(params, 2, buffer, size);
err = PA_GetLastError();
}
}
}
PA_ReturnLong(params, (long) err);
} // BlobTheRecord
// Declared for the 4D Developer as expecting:
// - a short (table number),
// - a BLOB
// - and return a long (error)
void BlobTheRecord (PA_PluginParameters params)
{
long size = 0;
PA_Handle theBlob;
char *theBlobPtr;
// Get the table number (first parameter)
tNum = PA_GetShortParameter(params, 1);
// transfer the data. In this case, it is more
// simple to just use the handle to the BLOB,
// since we do not have to modify it.
theBlob = PA_GetBlobHandleParameter(params, 2);
if(theBlob)
{
size = PA_GetHandleSize(theBlob);
theBlobPtr = PA_LockHandle(theBlob);// because perhaps 4D does things that may move memory?
PA_SetPackedRecord(tNum, theBlobPtr, size);
PA_UnlockHandle(theBlob);
}
PA_ReturnLong(params, (long) PA_GetLastError());
} // BlobTheRecord
See Also
Error Handling
Use
PA_GetLastError
to see if an error occurred (bad table number, insufficient memory, etc.).