[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [coldsync-hackers] Writing conduits that read more then one DB.
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
--
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.