Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re^8: Avoiding compound data in software and system design

by siracusa (Friar)
on Apr 30, 2010 at 00:39 UTC ( [id://837667]=note: print w/replies, xml ) Need Help??


in reply to Re^7: Avoiding compound data in software and system design
in thread Avoiding compound data in software and system design

I see. So you're volunteering to go through and modify all the 600+ DBD::* modules; and all the modules that use them; and all the code written in the last 15 years that use them; just so that you can provide introspection of things that nobody will ever want to introspect?

Is this really what you think I was suggesting? Or do you actually understand the context within which my previous post was made?

Let's just pretend for a moment that we could re-write history, and DBI had specified that the first parameter to DBI was a hashref.

Ah, it appears you do. I guess that first paragraph was just for "flavor," eh?

You would have a hash rather than a string. That would make it easier to wrapover in your DSN object--though this parsing you speak of is hardly onerous. But then, as now, that wrapover is pointless.

First, in my hypothetical version of DBI, I'd standardize the common names in the hash. For example, if you have something like a database, use the "database" key (not "db", not "dbname", etc.), use "host" for the host (not "hostname", not "server", etc.), and so on. This would be a documented part of DBI. Standardized names would cover at least half of the things commonly specified in DSNs.

Second, I think you still don't understand what Rose::DB actually does. Providing a nicer interface to DSNs is not its primary, or even secondary purpose. Even if it simply passed the registered data source information straight through to DBI, its most important roles would remain unchanged: first and foremost, to provide a uniform interface for database-specific behaviors to Rose::DB::Object; and second, as a registry of logically named data sources, organized in a generic two-level hierarchy (domain and type) with an optional file-based configuration overlay to allow sensitive information such as production passwords to be kept out of the source code, while still using exactly the same code in development and production.

To clarify that first role, the goal is to keep code out of Rose::DB::Object that says "if the database is mysql, do X, else if the database is oracle, do Y, else ..." and so on. (That goal is about 99% achieved; there are a few stragglers.) Instead, such behavior is delegated to the current Rose::DB-derived object, which is an object attribute in Rose::DB::Object (i.e., each Rose::DB::Object-derived object "has a" Rose::DB-derived object in its "db" attribute). This arrangements allows a Rose::DB::Object-derived object to, say, be loaded from one database and then stored into another, even if the two databases use a different server product, as shown in the tutorial. Assume "production" is PostgreSQL and "archive" is MySQL:

# My::DB "isa" Rose::DB $production_db = My::DB->new('production'); # PostgreSQL $archive_db = My::DB->new('archive'); # MySQL # Load bike from production database $p = Product->new(name => 'Bike', db => $production_db); $p->load; # Save the bike into the archive database $p->db($archive_db); $p->insert; # Delete the bike from the production database $p->db($production_db); $p->delete;

Again, understand that the Rose::DB::Object-derived Product object calls back into its Rose::DB-derived My::DB object whenever it does anything that might vary from one database to another. I hope you'll agree that Rose::DB is just a bit more than a "DSN object."

So, even if we could ignore history, and turn back the clock to do things your way, there'd be no value in it.

There'd be considerable value in that people could use DBI without constantly having to run "perldoc DBD::Whatever" to look up the driver-specific DSN syntax that they don't remember off the top of their head. There's also the added efficiency of not having to parse a string inside the DBD (and not having to write string parsing code in C, as it often is today), and being able to add new attributes without worrying if there's "room" in the current DSN syntax or having to make a second or third syntax, as many DBD::* modules have done, to accomodate new/different parameters. Finally, since a serialized format does actually have its uses (e.g., when stored in a file or sent over a network connection), DBI could support one or more of the standard formats that can be used to serialize a Perl hash into a string: JSON, YAML, Data::Dumper, etc.

Replies are listed 'Best First'.
Re^9: Avoiding compound data in software and system design
by BrowserUk (Patriarch) on Apr 30, 2010 at 06:52 UTC

    Two questions for you:

    1. Why would anyone use a Perl script, to back up a PostgreSQL production server, to a MySQL backup?

      When every RDBMS worthy of the name has archiving solutions that are safer, more reliable, often transparent, and faster. And that avoid all the obvious compatibility issues.

      PgSQL, DB2, Oracle, SQL Server, and even MySQL.

    2. How are you going to handle DBI_DSN, DBI_USER & DBI_PASS?

      Ancillary: How are you going to fit your hash into an environment variable (or 3)?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Why would anyone use a Perl script, to back up a PostgreSQL production server, to a MySQL backup?

      It's just an example. Most people only use one database type (though there are exceptions, and even scenarios just like the one described above; people do all sorts of things in the real world). But even when you're using just a single database, the particular, single set of database-specific behaviors you're invoking are delegeted to Rose::DB by Rose::DB::Object. That's the division of labor between the two modules that I was trying to illustrate.

      How are you going to handle DBI_DSN, DBI_USER & DBI_PASS? Ancillary: How are you going to fit your hash into an environment variable (or 3)?

      I covered that at the end of the last post: "since a serialized format does actually have its uses (e.g., when stored in a file or sent over a network connection), DBI could support one or more of the standard formats that can be used to serialize a Perl hash into a string: JSON, YAML, Data::Dumper, etc." Add to the examples "...or when stored in environment variables." User/pass could be kept as separate parameters or could be incorporated into the hash.

        It's just an example.

        A very poor example that does nothing to justify the need to objectify DSNs.

        Let's just assume for a moment that there is a legitimate purpose for using two different RDBMSs in a single application. And ignore that you can just open two standard DBI connections to them. And that Rose::DB has some useful part to play in that scenario(*). Then what is the need or benefit of Rose::DB abstracting the DSNs? Either as hashes or objects?

        • You cannot use the same hash/instance for both connections because they contain different information.
        • The only even vaguely consistantly common aspects across even just a sizeable subset are: the constant 'dbi'. and the user & pass fields.
        • And even if both connections have the latter two, it would probably be considered unwise to use the same userid and passwords for two different DBs.
        • You cannot validate any of the fields except the constants.
        • Beyond setting, getting and (re)serialising them, there are no useful methods that can be applied to them.

          Hence, they become nothing more than objectified structs.

        There is no advantage in hashifying or objectifying them

        And once you recognise that, there is certainly no benefit in trying to stuff multi-line serialisations of them into environment variables. And yes, I realise that some of those formats can be formatted as single lines, but have you ever tried editing them when formatted that way?

        Which means you'd now need to use some kind of tool to edit, then compact, them before stuffing the env vars. And that's a nonsense. It defeats the simplicity of purpose that environment variables have had for 40 years or more.

        And still you haven't given any specific reason for Rose::DB needing to have these "opaque tokens" broken out as structured entities rather than just leaving them as they are?

        And I mean needing! Not just a capricious choice.

        (*)(I'm not suggesting it doesn't, I just haven't gone into it enough to know one way or the other.)


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://837667]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2024-03-28 15:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found