Re[2]: [coldsync-hackers] Writing conduits that read more then one DB.

2 views
Skip to first unread message

Rob Bloodgood

unread,
Jun 6, 2003, 4:54:51 PM6/6/03
to coldsync...@googlegroups.com
Friday, June 6, 2003, 12:17:34 PM, you wrote:


IB> This is similar to my thinking, although I never thought of the possibility of
IB> allowing users to specify just the DB name without the path. If I take that
IB> approach, then I could do something like this:

IB> # Set default values
IB> %HEADERS = (
IB> File => "./TitraxTestOutput.txt"
IB> DBpath => InputDB =~ /(.*)\/.*$/
IB> Datebookdb => "DatebookDB.pdb"
IB> TitraxNoteDB => "TitraxNoteDB.pdb"
IB> TitraxDataDB => "TitraxDataDB.pdb"

IB> );

IB> Or not. This produces a syntax error. I'm guessing you can't set a hash
IB> value like this, or am I doing it wrong? Oh well, I'll just set DBpath from
IB> within my dump function. Unless there is a way to do what I'm trying here?

You need commas after the values.

The operator => is just a fancy comma, with the side affect that if
what's to the the left of it is a valid identifier, it gets
doublequoted. So, saying foo => "bar" is the same as "foo", "bar"
which gives you commas after your keys. But you ALSO need commas
after the values:

%HEADERS = (
File => "./TitraxTestOutput.txt",
DBpath => InputDB =~ /(.*)\/.*$/,
Datebookdb => "DatebookDB.pdb",
TitraxNoteDB => "TitraxNoteDB.pdb",
TitraxDataDB => "TitraxDataDB.pdb",

);

You'll notice a stray comma on the last one. This is a non-error in
perl, and convenient if you ever add more entries to the hash, because
the comma is "already there" and prevents the syntax errors you saw.

HTH!

L8r,
Rob

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

Christophe Beauregard

unread,
Jun 6, 2003, 9:54:21 PM6/6/03
to coldsync...@googlegroups.com
On Friday 06 June 2003 20:05, Izzy Blacklock wrote:

> if !defined $HEADERS{ DBpath }
> {
> ( $HEADERS{ DBpath } = $HEADERS{ InputDB } ) =~ !(.*)/.*$!$1!;
> }
>
> This is what I'm doing now. I'd still like to be able to load it as a
> default value in the hash above before the headers are processed though.
> If anyone has suggestions of how this could be done, I'd love to here
> them! ;)

That's what I was thinking while following the thread.

$HEADERS{InputDB} isn't set until StartConduit/ConduitMain runs, so anything
you do before that is just wishful thinking. But StartConduit/ConduitMain
rely on sane defaults in %HEADERS and you want DBpath mentioned so the
-config command line works, so you want something useful as a default.
Circular dependency, right?

What I'm wondering is why you'd even want to allow the user to define the
path of the .pdb's? If they aren't all in the same location as InputDB,
you're basically syncing Palm databases from somewhere that coldsync
doesn't know anything about. That... doesn't seem right.

If you assume that all the databases are where InputDB is, then there's no
reason why you need to fuss with trying to get the path into %HEADERS at
all. $HEADERS{InputDB} will be set for you and that's all you need, right?
Okay, maybe the database _names_ could be defined there, but the user has
already configured that path in the "palm" section of the configuration...

Er... which is also where $HEADER{PDA-Directory} is derived from, isn't it?
Which would mean that the databases are all supposed to be in
"$HEADER{PDA-Directory}/backup"?

So all $HEADER{InputDB} is useful for is as a database that has conveniently
been opened for you by StartConduit:
------------------------------------------------------------------------------------------


%HEADERS = (
File => "./TitraxTestOutput.txt",

);

StartConduit('dump');

my %pdbs;

foreach( qw(Datebookdb TitraxNoteDB TitraxDataDB TitraxNameDB) ) {
($pdbs{$_} = $PDB and next) if $PDB->{name} eq $_;

$pdsb{$_} = new Palm::PDB;
$pdbs{$_}->Load( $HEADER{PDA-Directory} . "/backup/" . $_ . ".pdb" );
}

------------------------------------------------------------------------------------------

I suppose you could allow the user to specify the names of all the databases
in the config in which case you'd need to map your internal names to
whatever the user specifies.

But the gist of all that is you end up with four open databases each
accessible as $pdbs{<dbname>}.

If you want to write at the end of the conduit, you do need something like:
------------------------------------------------------------------------------------------
foreach( values %pdbs ) {
$_->Write( $HEADER{PDA-Directory} . "/backup/" . $_->{name} . ".pdb" );
}
------------------------------------------------------------------------------------------

Anyhow, my two cents. I'm pretty new to this conduit thing myself.

c.

Izzy Blacklock

unread,
Jun 4, 2003, 10:09:49 PM6/4/03
to coldsync...@googlegroups.com
I'd sent a message earlier but suspect that it didn't make it to the list
because I hadn't verified my subscription yet. :( I've since learned more
about coldsync and the Palm modules, so hopefully these questions will be a
little more intelligent! ;)

WARNING: A perlmonk I am not. This is my first go at writing anything
serious in Perl, so go easy on me! :)

What I'm trying to do is write a new conduit for Titrax. The existing one
seems to be written for an earlier version of Titrax and isn't complete
anyway. It only extracts Titrax data from the datebook db and is looking for
the string "Titrax log" in the datebooks description; which doesn't appear
(I'm assuming it did in older versions).

Titrax however, has the ability to also store logs in it's own notes, which
the current conduit doesn't handle. In addition to the data that Titrax can
put into the datebook database, it also has tree DBs of it's own:

TitraxDataDB.pdb -- Database of Project Times (I'm guessing)
TitraxNameDB.pdb -- Database of Project names
TitraxNoteDB.pdb -- Database of Project Notes

Obviousely this means I need to look for data in 4 sources. At present, I'm
not too concerned with the data in TitraxDataDB.pdb. The logs held either in
the datebook or TitraxNotesDB are what's important. The TitraxNameDB is also
important since it holds the project names as they appear in the Datebooks
description field. Also, the TitraxNoteDB is cross indexed with it. ie, the
project name for record 5 in the noteDB is record 5 in the NameDB. The three
databases created by Titrax all have creator ttrx, and types of data, name,
or note.

What I need to do is build a conduit that will read the TitraxNameDB, then
check for notes in TitraxNoteDB and look for Databook records that have
descriptions matching the TitraxNameDB entries. My first message questioned
whether it was possible to pass more then one InputDB header entry. I
suspect this isn't possible, and the better solution would be to pass
arguments with the names of the extra pdb files to check.

I'm thinking of building my conduit to use a config like this:

conduit dump {
path: /path/to/conduit/titrax;
type: ttrx/name;
arguments:
DBpath: /path/to/user/.palm/backup
Datebookdb: /path/to/user/.palm/backup/DatebookDB.pdb
TitraxNoteDB: /path/to/user/.palm/backup/TitraxNoteDB.pdb
TitraxDataDB: /path/to/user/.palm/backup/TitraxDataDB.pdb
}

My intention is that the last three arguments would be optional if DBpath is
set. If none of the arguments are set, I'm thinking I can pull the path off
of InputDB, which would be set to /path/to/usr/.palm/backup/TitraxNameDB.pdb
(I think) given this config.

Does this sound like a reasonable approach? Are there better ways to handle
palm apps that have/use multiple DBs? Assuming this is a reasonable
approach, my next question becomes, what's the best way to implement it?

Looking at Palm::PDB, it seems to only be designed for dealing with one file
at a time. Given this constraint, I'm thinking I should create three sub
classes (one for each file) derived from Palm::raw. This seems ugly, so if
someone has a better idea, please speak up! ;) It'd be nice just to have
Palm::Titrax, not Palm::TitraxName, Palm::TitraxData, Palm::TitraxNote.

If I take this approach, then I'd need a container class to hold four PDB
objects; three Titrax DBs and one Datebook. The current coldsync class only
holds one. Should I create a new class derived from coldsync to accommodate
the extra PDBs or just code a conduit with three local PDB objects?

Due to my limited Perl experience, I'm probably making this more
difficult/ugly then it needs to be. If there are better/easier ways to code
this, please let me know.

...Izzy

Andrew Arensburger

unread,
Jun 5, 2003, 8:11:53 PM6/5/03
to coldsync...@googlegroups.com
On Wed, 4 Jun 2003, Izzy Blacklock wrote:
> WARNING: A perlmonk I am not. This is my first go at writing anything
> serious in Perl, so go easy on me! :)

See http://www.ooblick.com/text/perl/, if I may be forgiven some
shameless self-advertising.

> What I'm trying to do is write a new conduit for Titrax.

[snip description]


> Obviousely this means I need to look for data in 4 sources. At present, I'm
> not too concerned with the data in TitraxDataDB.pdb. The logs held either in
> the datebook or TitraxNotesDB are what's important. The TitraxNameDB is also
> important since it holds the project names as they appear in the Datebooks
> description field. Also, the TitraxNoteDB is cross indexed with it. ie, the
> project name for record 5 in the noteDB is record 5 in the NameDB. The three
> databases created by Titrax all have creator ttrx, and types of data, name,
> or note.
>
> What I need to do is build a conduit that will read the TitraxNameDB, then
> check for notes in TitraxNoteDB and look for Databook records that have
> descriptions matching the TitraxNameDB entries. My first message questioned
> whether it was possible to pass more then one InputDB header entry. I
> suspect this isn't possible,

Correct.

> and the better solution would be to pass
> arguments with the names of the extra pdb files to check.

Also correct.

> I'm thinking of building my conduit to use a config like this:
>
> conduit dump {
> path: /path/to/conduit/titrax;
> type: ttrx/name;
> arguments:
> DBpath: /path/to/user/.palm/backup
> Datebookdb: /path/to/user/.palm/backup/DatebookDB.pdb
> TitraxNoteDB: /path/to/user/.palm/backup/TitraxNoteDB.pdb
> TitraxDataDB: /path/to/user/.palm/backup/TitraxDataDB.pdb
> }
>
> My intention is that the last three arguments would be optional if DBpath is
> set. If none of the arguments are set, I'm thinking I can pull the path off
> of InputDB, which would be set to /path/to/usr/.palm/backup/TitraxNameDB.pdb
> (I think) given this config.

This sounds reasonable. Personally, I would write the conduit to
use the arguments above as default values. That is, by default it will
assume that the Note database is "TitraxNoteDB.pdb", and is located in the
same directory as InputDB (that is, take InputDB and chop off everything
after the last "/").
If the "TitraxNoteDB" argument is given, see if its value begins
with a slash. If yes, then use the value as the path to the database.
Otherwise, use it as a relative pathname under the default directory.

> Does this sound like a reasonable approach? Are there better ways to handle
> palm apps that have/use multiple DBs? Assuming this is a reasonable
> approach, my next question becomes, what's the best way to implement it?
>
> Looking at Palm::PDB, it seems to only be designed for dealing with one file
> at a time.

I'm not sure what you mean about this. See below.

> Given this constraint, I'm thinking I should create three sub
> classes (one for each file) derived from Palm::raw. This seems ugly, so if
> someone has a better idea, please speak up! ;) It'd be nice just to have
> Palm::Titrax, not Palm::TitraxName, Palm::TitraxData, Palm::TitraxNote.

Well, you could always go with Palm::Titrax::Name,
Palm::Titrax::Data, and Palm::Titrax::Note. This seems reasonably perlish.

You said that Palm::PDB seems to be designed for dealing with only
one file at a time. Actually, each subclass of Palm::PDB is intended to
deal with only one _type_ of file. However, you can handle multiple files
of the same type:

use Palm::Memo;

$memo1 = new Palm::PDB;
$memo1->Load("Memo1.pdb");

$memo2 = new Palm::PDB;
$memo2->Load("Memo2.pdb");

> If I take this approach, then I'd need a container class to hold four PDB
> objects; three Titrax DBs and one Datebook. The current coldsync class only
> holds one. Should I create a new class derived from coldsync to accommodate
> the extra PDBs or just code a conduit with three local PDB objects?

Go with whatever you feel most comfortable with. I think both
approaches are defensible. I guess the main criteria should be the extent
to which you think you might reuse your code, and how much the extra
encapsulation might get you.
If you're used to C++- or Java-style object-oriented coding, it
may come as a shock to learn that in Perl, you can just reach into another
class or object and use its methods and members (you're discouraged from
doing this because it isn't polite, is all).
In particular, take a look at the ParseArgs and ReadHeaders
functions inside ColdSync.pm. They're just functions, not methods, so you
can, in principle, use

use ColdSync;

&ColdSync::ParseArgs(@ARGV);
&ColdSync::ReadHeaders();

However, RTFS before you do this, to make sure they'll work for you.
They're not documented, which is the standard Perl way of telling people
not to use a certain function, but I don't remember whether this was
because I thought they'd break if used outside of the ColdSync module, or
simply because I hadn't cleaned them up to make this easy.

In other words, there's nothing magical about the ColdSync module:
it just provides a convenient way to implement the most common type of
conduit, but the ColdSync<->conduit interaction is fairly simple. See the
"ColdSync Conduits" texinfo file for more details.
So if it were me, I'd just raid ColdSync.pm for useful code and do
things by hand, rather than subclassing it or whatever.

The other possible class, which might be more useful, would be one
that unites the four files being used.
If you just load the four files, you'll have to keep track of
relationships like the one you mentioned above:

: Also, the TitraxNoteDB is cross indexed with it. ie, the


: project name for record 5 in the noteDB is record 5 in the NameDB.

So if you delete NoteDB record #5, you'll also need to delete NameDB
record #5. Presumably you'll write some helper functions to do this. If
there's a lot of this sort of thing going on, you may want to write a
Titrax class that keeps track of everything (it need not be subclassed
from anything, since Titrax _has-a_ Titrax::Data, but not Titrax _is-a_
Titrax::Data).
But I guess this is a bit of a tangent.

> Due to my limited Perl experience, I'm probably making this more
> difficult/ugly then it needs to be. If there are better/easier ways to
> code this, please let me know.

"more difficult/ugly" depends on what you're trying to do. You may
want to start out doing it by hand (looting^Wadapting code from
ColdSync.pm if it seems useful), and see what you actually need.

Having said this, there's nothing that says you need to do this in
Perl. ColdSync communicates with conduits using nothing more than
command-line arguments, stdin/stdout, and a few environment variables.
If you're more comfortable with Python, Ruby, C++, Lisp, or
whatever, and are willing to spend the time to write a module that'll make
it easier to write conduits in that language, then by all means write it
and send it in.

--
Andrew Arensburger Actually, these _do_ represent the
are...@ooblick.com opinions of ooblick.com!
Generic Tagline V 6.01

Izzy Blacklock

unread,
Jun 6, 2003, 3:17:34 PM6/6/03
to coldsync...@googlegroups.com
On June 5, 2003 06:11 pm, Andrew Arensburger wrote:
> On Wed, 4 Jun 2003, Izzy Blacklock wrote:
> > WARNING: A perlmonk I am not. This is my first go at writing anything
> > serious in Perl, so go easy on me! :)
>
> See http://www.ooblick.com/text/perl/, if I may be forgiven some
> shameless self-advertising.

Thanks. I'd found them already. It's come in handy to help clarify some
things for me. :) I also have the Perl Cookbook and browsers open to
Perldoc.com, Perlmonks.net, and search.cpan.org. With such a wealth of
information around, perl is turning out to be quite an easy language to
learn! :)

I've played with it on and off for a while, but I've never had the time to
really do much more then make small changes to code from others. My NEED for
a working Titrax conduit has given me the incentive to do something a little
more meaningfull with it. :)

> > I'm thinking of building my conduit to use a config like this:
> >
> > conduit dump {
> > path: /path/to/conduit/titrax;
> > type: ttrx/name;
> > arguments:
> > DBpath: /path/to/user/.palm/backup
> > Datebookdb: /path/to/user/.palm/backup/DatebookDB.pdb
> > TitraxNoteDB: /path/to/user/.palm/backup/TitraxNoteDB.pdb
> > TitraxDataDB: /path/to/user/.palm/backup/TitraxDataDB.pdb
> > }
> >
> > My intention is that the last three arguments would be optional if DBpath
> > is set. If none of the arguments are set, I'm thinking I can pull the
> > path off of InputDB, which would be set to
> > /path/to/usr/.palm/backup/TitraxNameDB.pdb (I think) given this config.
>
> This sounds reasonable. Personally, I would write the conduit to
> use the arguments above as default values. That is, by default it will
> assume that the Note database is "TitraxNoteDB.pdb", and is located in the
> same directory as InputDB (that is, take InputDB and chop off everything
> after the last "/").
> If the "TitraxNoteDB" argument is given, see if its value begins
> with a slash. If yes, then use the value as the path to the database.
> Otherwise, use it as a relative pathname under the default directory.

This is similar to my thinking, although I never thought of the possibility of

allowing users to specify just the DB name without the path. If I take that

approach, then I could do something like this:

# Set default values


%HEADERS = (
File => "./TitraxTestOutput.txt"

DBpath => InputDB =~ /(.*)\/.*$/

Datebookdb => "DatebookDB.pdb"
TitraxNoteDB => "TitraxNoteDB.pdb"
TitraxDataDB => "TitraxDataDB.pdb"

);

Or not. This produces a syntax error. I'm guessing you can't set a hash

value like this, or am I doing it wrong? Oh well, I'll just set DBpath from

within my dump function. Unless there is a way to do what I'm trying here?

> > Given this constraint, I'm thinking I should create three sub


> > classes (one for each file) derived from Palm::raw. This seems ugly, so
> > if someone has a better idea, please speak up! ;) It'd be nice just to
> > have Palm::Titrax, not Palm::TitraxName, Palm::TitraxData,
> > Palm::TitraxNote.
>
> Well, you could always go with Palm::Titrax::Name,
> Palm::Titrax::Data, and Palm::Titrax::Note. This seems reasonably perlish.

Ok, that makes sense. If I understand modules correctly, I'd just create three
.pm files, one for each of the data types, and put them all into a
Palm/Titrax folder. Than use package Palm::Titrax::Name, etc.

> You said that Palm::PDB seems to be designed for dealing with only
> one file at a time. Actually, each subclass of Palm::PDB is intended to
> deal with only one _type_ of file. However, you can handle multiple files
> of the same type:
>
> use Palm::Memo;
>
> $memo1 = new Palm::PDB;
> $memo1->Load("Memo1.pdb");
>
> $memo2 = new Palm::PDB;
> $memo2->Load("Memo2.pdb");

That is what I was asking. I had the idea in my head of creating a single
subclass of Palm::PDB that would deal with all the files at once. This
doesn't seem like a reasonable, or possible approach anymore.

> > If I take this approach, then I'd need a container class to hold four PDB
> > objects; three Titrax DBs and one Datebook. The current coldsync class
> > only holds one. Should I create a new class derived from coldsync to
> > accommodate the extra PDBs or just code a conduit with three local PDB
> > objects?
>
> Go with whatever you feel most comfortable with. I think both
> approaches are defensible. I guess the main criteria should be the extent
> to which you think you might reuse your code, and how much the extra
> encapsulation might get you.

Probably not much. I'm working on a simple dump function for now. I've taken
the approach of using three local PDB objects (well, actually two, I don't
need the data from TitraxDataDB). As I build sync and fetch functions, I'll
look at whether encapsulating things into a module would be useful or not.
For now, I'm happy with the results I'm getting! ;)

> If you're used to C++- or Java-style object-oriented coding, it
> may come as a shock to learn that in Perl, you can just reach into another
> class or object and use its methods and members (you're discouraged from
> doing this because it isn't polite, is all).

I cut my OO teeth on C++. I've never done much with it, but learned the
principles of OO on it. I was a little surprised at first to learn that perl
didn't really have private members, but in the big scheme of things, I doubt
it matters. It's not like you could "accidently" mess with members of
another module. If you chose to, then any bugs that is created is your own
fault, right! ;)

> In particular, take a look at the ParseArgs and ReadHeaders
> functions inside ColdSync.pm. They're just functions, not methods, so you
> can, in principle, use
>
> use ColdSync;
>
> &ColdSync::ParseArgs(@ARGV);
> &ColdSync::ReadHeaders();
>
> However, RTFS before you do this, to make sure they'll work for you.
> They're not documented, which is the standard Perl way of telling people
> not to use a certain function, but I don't remember whether this was
> because I thought they'd break if used outside of the ColdSync module, or
> simply because I hadn't cleaned them up to make this easy.

I guess if ReadHeaders() isn't a method, I can't overload it to handle my
DBpath from above. If I understand correctly, to make ReadHeaders() a
method, I'd just add it to @EXPORT. Could I then do something like this
(assuming my logic is correct):

sub ReadHeaders {
&ColdSync::ReadHeaders();
if ( !defined $HEADERS{DBpath} {
( $HEADERS{ DBpath } = $HEADERS{ InputDB } ) =~ s!(.*)/.*$!$1!;
}
}


> In other words, there's nothing magical about the ColdSync module:
> it just provides a convenient way to implement the most common type of
> conduit, but the ColdSync<->conduit interaction is fairly simple. See the
> "ColdSync Conduits" texinfo file for more details.
> So if it were me, I'd just raid ColdSync.pm for useful code and do
> things by hand, rather than subclassing it or whatever.
>
> The other possible class, which might be more useful, would be one
> that unites the four files being used.
> If you just load the four files, you'll have to keep track of
>
> relationships like the one you mentioned above:
> : Also, the TitraxNoteDB is cross indexed with it. ie, the
> : project name for record 5 in the noteDB is record 5 in the NameDB.
>
> So if you delete NoteDB record #5, you'll also need to delete NameDB
> record #5. Presumably you'll write some helper functions to do this. If
> there's a lot of this sort of thing going on, you may want to write a
> Titrax class that keeps track of everything (it need not be subclassed
> from anything, since Titrax _has-a_ Titrax::Data, but not Titrax _is-a_
> Titrax::Data).
> But I guess this is a bit of a tangent.

I was thinking more along the lines of Titrax _is-a_ Coldsync, which _has-a_
Palm::Titrax::Data, Palm::Titrax::Name, Palm::Titrax::Note, and
Palm::Datebook; all being Palm::PDB objects. Coldsync provides the first
PDB object, a Coldsync::Titrax would need to create three more and provide
the logic which ties them together.

I don't like the idea of simply raiding ColdSync.pm for my needs. It's a
simple answer, but it defeats the purpose of OO design. Not to mention I'd
have to watch your code for changes to the parts I raided.

For now, I'm just creating the extra PDB objects within my conduit functions.
It's the simplest way to get what I need done. :)

>
> > Due to my limited Perl experience, I'm probably making this more
> > difficult/ugly then it needs to be. If there are better/easier ways to
> > code this, please let me know.
>
> "more difficult/ugly" depends on what you're trying to do. You may
> want to start out doing it by hand (looting^Wadapting code from
> ColdSync.pm if it seems useful), and see what you actually need.
>
> Having said this, there's nothing that says you need to do this in
> Perl. ColdSync communicates with conduits using nothing more than
> command-line arguments, stdin/stdout, and a few environment variables.
> If you're more comfortable with Python, Ruby, C++, Lisp, or
> whatever, and are willing to spend the time to write a module that'll make
> it easier to write conduits in that language, then by all means write it
> and send it in.

Perhaps one day. I've been meaning to learn Python and creating a Python
interface to Coldsync would give me a project to learn with! ;)
...If only there were more time in a day! :( ...

...Izzy

Izzy Blacklock

unread,
Jun 6, 2003, 8:05:04 PM6/6/03
to coldsync...@googlegroups.com

Thanks Rob,

Sadly, it still doesn't work the way I'd hoped. Part of the problem seems to
be that InputDB =~ /(.*)\/.*$/ doesn't actually return a scalar. It works
when I print, but attempts to assign the result to a scaler returns a number
(the number of matches I believe). It seems to do what I want, I'd need to
do something like:

( $HEADERS{ DBpath } = $HEADERS{ InputDB } ) =~ !(.*)/.*$!$1!;

Which does have the desired effect but isn't usable above. If I use it in a
function after the headers have been processed, then I'd want to test that
DBpath didn't have a valid entry first. Something like this:

if !defined $HEADERS{ DBpath }
{
( $HEADERS{ DBpath } = $HEADERS{ InputDB } ) =~ !(.*)/.*$!$1!;
}

This is what I'm doing now. I'd still like to be able to load it as a default
value in the hash above before the headers are processed though. If anyone
has suggestions of how this could be done, I'd love to here them! ;)

I'm sure there are other places my code could be improved as well. I'm
currently working on parsing the data from the TitraxNotesDB. I already have
it reading the data out of the DatebookDB. At this point, I'm really just
extracting the data and dumping it to a text file. Once I'm done I could
post what I have here for some feedback. If that's OK with Andrew that is.

Once it's finished and does something useful (I'm thinking formated text
output, HTML output, and SQL output), I'll make it available as a package for
anyone interested. My specific interests are with the SQL output. I'm
planning on building a weblet for displaying and modifying the data from the
database.

...Izzy

Izzy Blacklock

unread,
Jun 7, 2003, 1:18:59 PM6/7/03
to coldsync...@googlegroups.com
On June 6, 2003 07:54 pm, Christophe Beauregard wrote:
> On Friday 06 June 2003 20:05, Izzy Blacklock wrote:
> > if !defined $HEADERS{ DBpath }
> > {
> > ( $HEADERS{ DBpath } = $HEADERS{ InputDB } ) =~ !(.*)/.*$!$1!;
> > }
> >
> > This is what I'm doing now. I'd still like to be able to load it as a
> > default value in the hash above before the headers are processed though.
> > If anyone has suggestions of how this could be done, I'd love to here
> > them! ;)
>
> That's what I was thinking while following the thread.
>
> $HEADERS{InputDB} isn't set until StartConduit/ConduitMain runs, so
> anything you do before that is just wishful thinking. But
> StartConduit/ConduitMain rely on sane defaults in %HEADERS and you want
> DBpath mentioned so the -config command line works, so you want something
> useful as a default. Circular dependency, right?

You know, I think your right. $HEADERS wont be filled at this point, so I
can't use one value to set another in this case. But assuming that this
wasn't a problem, is it possible to do what I was trying to do? Just In case
I run into it again.

> What I'm wondering is why you'd even want to allow the user to define the
> path of the .pdb's? If they aren't all in the same location as InputDB,
> you're basically syncing Palm databases from somewhere that coldsync
> doesn't know anything about. That... doesn't seem right.

You do have a point. My aim was just to be flexible. Who knows what a user
in the future might want to do with it. One valid reason that someone might
want this option is if they wanted to parse an old backup stored in a
different location. They could manually call the conduit with a script like
this:

#!/bin/bash
echo 'Daemon: coldsync
Version: 2.1.2
InputDB: /my/palm/backup/TitraxNameDB.pdb
TitraxNoteDB: /my/palm/backup/TitraxNote.pdb
File: ./titrax.txt
' | ./TitraxConduit conduit dump

> If you assume that all the databases are where InputDB is, then there's no
> reason why you need to fuss with trying to get the path into %HEADERS at
> all. $HEADERS{InputDB} will be set for you and that's all you need, right?
> Okay, maybe the database _names_ could be defined there, but the user has
> already configured that path in the "palm" section of the configuration...
>
> Er... which is also where $HEADER{PDA-Directory} is derived from, isn't it?
> Which would mean that the databases are all supposed to be in
> "$HEADER{PDA-Directory}/backup"?

I didn't know about PDA-Directory. I'll poke around in the code a little
more. This may be an alternate way for me to get/set the DBpath I'm looking
for. For flexability, I still want a DBpath option available for the user
though, but if they don't set it, I need to provide a sane default.

> So all $HEADER{InputDB} is useful for is as a database that has
> conveniently been opened for you by StartConduit:
> ---------------------------------------------------------------------------

>--------------- %HEADERS = (


> File => "./TitraxTestOutput.txt",
> );
>
> StartConduit('dump');
>
> my %pdbs;
>
> foreach( qw(Datebookdb TitraxNoteDB TitraxDataDB TitraxNameDB) ) {
> ($pdbs{$_} = $PDB and next) if $PDB->{name} eq $_;
>
> $pdsb{$_} = new Palm::PDB;
> $pdbs{$_}->Load( $HEADER{PDA-Directory} . "/backup/" . $_ . ".pdb" );
> }
>
> ---------------------------------------------------------------------------
>---------------

I like it! :) That's a much more elegant way then creating a local scalar for
each! :) Of course I couldn't allow the user to specify different locations
for each of the DB files this way. But that would be a pretty far fetched
need anyway. Perhaps it would be enough just to allow them to specify an
alternate location for the DB files. Even then, if they provide an alternate
location of the InputDB file, that would give me the alternate path, assuming
all .pdbs are in the same location.

Excuse me for thinking out loud, but I think you might have something here,
which has caused me to rethink my approach. :)

>
> I suppose you could allow the user to specify the names of all the
> databases in the config in which case you'd need to map your internal names
> to whatever the user specifies.
>
> But the gist of all that is you end up with four open databases each
> accessible as $pdbs{<dbname>}.
>
> If you want to write at the end of the conduit, you do need something like:
> ---------------------------------------------------------------------------

>--------------- foreach( values %pdbs ) {


> $_->Write( $HEADER{PDA-Directory} . "/backup/" . $_->{name} . ".pdb" );
> }
> ---------------------------------------------------------------------------
>---------------
>
> Anyhow, my two cents. I'm pretty new to this conduit thing myself.

That's OK, your obviousely more experienced with Perl then me. I appreciate
your feedback. I think I may have learned something! ;)

...Izzy

Reply all
Reply to author
Forward
0 new messages