[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [coldsync-hackers] SPC and writing records



On Wednesday 07 July 2004 11:22, Marco van Beek wrote:
> I assume that before I use dlpWriteRecord, I need to "pack" the data
> into a suitable format. Has anyone got an example of this they could
> send me?

Depends on what database you're writing. 

In general, you should really use a Palm::PDB helper. Then a record write 
looks something like (and beware, I'm writing all the code in this message 
off the top of my head):

  use Palm::Datebook;
  my $rec = Palm::Datebook->new_Record();
  fill_record( $rec );
  my $dbh = dlp_OpenDB( 'DatebookDB', 0x80|0x40 );
  ($err,$retval,$rec->{'id'}) = dlp_WriteRecord( $dbh,
  	$rec->{'id'}, Palm::Datebook->PackRecord($rec) );
  dlp_CloseDB( $dbh );

dlp_WriteRecord() creates sane defaults if you leave the last three 
parameters out (category,attributes,flags).

For examples that actually work, the install-(text|html|pdf) conduits I 
posted yesterday (?) do exactly this using the Palm::Doc helper:

   for( @{$doc->{'records'}} ) {
      dlp_WriteRecord( $dbh, 0, $doc->PackRecord($_) );
   }

Or you can use ColdSync::PDB which blends the Palm::PDB logic with SPC and 
hence hides the entire packing concept, not to mention the flags and 
attributes and whatnot:

  my $dbh = ColdSync::PDB->Load( 'DatebookDB', 'rw' );
  my $rec = $dbh->newRecord();
  fill_record( $rec );
  $dbh->WriteRecord( $rec );
  undef $dbh;

If you don't have a Palm::PDB helper to work with, you need to manually pack 
to the C structure. So if the corresponding C record looked like:

  typedef struct my_record_t {
  	short number;
	unsigned char flag;
	char* name; /* NUL terminated */
  };

You'd do something like:

  my $rec = { 'number' => $some_val1, 'flag' => 1, 'name' => $some_val2 };
  my $data = pack( 'n C a*x',
  	$rec->{'number'}, $rec->{'flag'}, $rec->{'name'} );
  ($err,$retval,$rec->{'id'}) = dlp_WriteRecord( $dbh, $id, $data );

If you care at all about clean design and reusability, you'd be best off 
writing a Palm::PDB module to handle the structure. Even if it's just a 
minimal implementation with PackRecord() and ParseRecord(). i.e.

  package Palm::MyRecord;
  use vars qw(@ISA $VERSION);
  @ISA = qw(Palm::PDB);
  $VERSION = 0.1;
  sub import {
     &Palm::PDB::RegisterPDBHandlers( __PACKAGE__, [ $creator, $type ], );
  }
  sub PackRecord($$) {
  	my ($self,$rec) = @_;
	return pack( 'n C a*x',
	  	$rec->{'number'}, $rec->{'flag'}, $rec->{'name'} );
  }
  sub ParseRecord($$) {
  	my ($self,$data) = @_;
	my %ret;
	@ret{'number','flag','name'} = unpack('n C a*', $data );
	$ret{'name'} =~ s/\0$//; # trim trailing NUL
	return \%ret;
  }

Hmmm... That was probably Way More Information than you wanted.

c.
This message was sent through the coldsync-hackers mailing list.  To remove
yourself from this mailing list, send a message to majordomo@thedotin.net
with the words "unsubscribe coldsync-hackers" in the message body.  For more
information on Coldsync, send mail to coldsync-hackers-owner@thedotin.net.