KirbyBase

Discussion in 'Ruby' started by rubyhacker@gmail.com, Sep 8, 2005.

  1. Guest

    I'm posting from work, but will try to follow up in more
    detail when I get home.

    For the record, KirbyBase is cool. Jamey has done an amazing
    job on it, and it works well and is intuitive.

    If you need gigantic tables, if you need SQL, if you need
    20K transactions per second -- don't use it. :)

    But if you need a lightweight, low-profile data storage
    mechanism with a good Rubylike interface, then do use it.

    Many of the recent developments in it have been driven in part
    by me. I have had a few ideas which Jamey was kind enough to
    implement. All credit for the code goes to him. I haven't
    written a line of the engine.

    But Jamey and I have a slight disconnect in our communication
    which is almost an object of study in itself.

    Aside: I had a CS prof, Tobin Maginnis, with degrees in
    psychology. He was always interested in research into the
    psychology of human interfaces and of the coding process.
    I bet he would love to watch Jamey and me and take notes. ;)

    The thing is, Jamey is a Database Guy. As the sole architect
    and coder of KirbyBase, this is a Good Thing.

    Me, I'm just a guy who has objects he wants to store and retrieve.
    In fact, I have looked at Madeleine and such. I'm not married
    to the idea of a database at all, as long as I can store and
    retrieve my objects.

    As an Object Guy, I don't want too many of the details of the
    database to intrude into my code (or especially into my classes).
    I want the wires hidden from the audience. I want to pay no
    attention to that man behind the curtain. I want it as blackboxy
    as it can reasonably be.

    For a past example: When I started uaing KB, a select would
    return me an array of fields. I would take those fields and use
    them to construct an object. It got to be a pain when I wanted to load
    an object, change it, and store it back (decomposing it back
    into an array before storing).

    Eventually I said: Why am I doing this? And Jamey and I hammered
    something out. Now when I do a select, I get an object back; and
    when I store an object, I don't have to convert it.

    Some of my basic principles are:

    1. Software should be my servant, not my master.
    2. My servant should be smart and read my mind whenever
    possible. I don't want to micromanage him.
    3. At the same time, if I have very complex or specific needs,
    I want him to be able to accept micromanagement.
    4. In connection with #2, common or ordinary actions should be
    easy.
    5. In connection with #3, infrequent or extraordinary actions
    may be more complex. (Think Zipf's Law. Also remember DHH's
    "say no by default.")

    This to me is the essence of why I like Ruby (and by extension
    why I like Rails).

    Now, how does this relate to KirbyBase? I'll get into specifics
    later on.


    Cheers,
    Hal
    , Sep 8, 2005
    #1
    1. Advertising

  2. wrote:
    [interesting anecdote snipped]
    > Some of my basic principles are:
    >
    > 1. Software should be my servant, not my master.
    > 2. My servant should be smart and read my mind whenever
    > possible. I don't want to micromanage him.
    > 3. At the same time, if I have very complex or specific needs,
    > I want him to be able to accept micromanagement.
    > 4. In connection with #2, common or ordinary actions should be
    > easy.
    > 5. In connection with #3, infrequent or extraordinary actions
    > may be more complex. (Think Zipf's Law. Also remember DHH's
    > "say no by default.")


    I heartily agree with these principles. In fact I'd go so far as to say
    these principles can apply to all technology, not just software. Even
    though I'm a computer engineer and love technology, I still fear that in
    many ways we are becoming slaves to it, and not the other way around.

    So in this way I try my best to pull back at times and look at the big
    picture to ask myself: "how is this making my life better?" Because
    sometimes I'm just playing with technology for the sake of playing with
    technology. This isn't bad in all cases, but it can be if that is all
    you ever do.

    > This to me is the essence of why I like Ruby (and by extension
    > why I like Rails).


    Same here.

    > Now, how does this relate to KirbyBase? I'll get into specifics
    > later on.


    I look forward to reading more.

    Ryan
    Ryan Leavengood, Sep 9, 2005
    #2
    1. Advertising

  3. Guest

    Well, I didn't get to make this post last night. :-/ Things such as
    work, food, and sleep really interfere with coding and posting.

    I'll make a few comments now and flesh them out later.

    As I said, I'm an Object Guy and Jamey is a Database Guy. What does
    that mean?

    I was working on an app and using KirbyBase. Because of the work Jamey
    had done recently, creating objects from the database records was much
    easier.

    But I noticed something. My fields were all simple types. (After all,
    that's how databases work.) But I was taking my smaller objects and
    using them to build bigger objects. In most cases, I was storing a key
    into another table. So I would look up a record, and four of its fields

    would actually be keys into other tables. I'd then look up those four.
    I'd then embed my four little objects inside an object corresponding to

    the original row.

    I had a feeling that I was doing too much work, that some of this could

    be done for me.

    My thoughts were like this: OK, we have primitive types such as integer

    and string. From OOP, I have a habit of thinking of classes as abstract

    types (see Bertrand Meyer -- I think).

    So if I want an object to have a member which is (e.g.) a Person, why
    can't I treat Person just like String and Integer?

    In Ruby, we don't think of variables or attributes as being typed. I
    make an exception in the case of retrieving objects from databases,
    because I am very used to the idea of fields having types. (Although
    someday I will comment on that also.)

    After all, even in Ruby, we often think to ourselves, "This member
    will be a string" -- although if we are not careful, we might assign
    any other thing to it. But I won't go off on too much of a tangent
    here.

    So here I am. I'm thinking: Treat simple types (simple fields) the way
    we already do. We store a type for each field. Let's store the complex
    types the same way... but in the actual table, just store a key into
    another table.

    That requires the table name and key field name to be specified
    somehow,
    of course. My take: Let's get slightly railsy and assume the class name

    lowercased is the table name (e.g. Person => person.tbl). That means we

    only have to specify the field name explicitly (and I've been thinking
    of a way to eliminate that also, by optionally establishing a known
    "key field" for a table).

    I was thinking "composite objects." I was thinking "embedding simpler
    objects inside more complex ones." I was thinking "this is how I can
    easily and transparently marshal my objects."

    When I mentioned this to Jamey, he said in effect, "Oh, you want one-
    to-one links between database tables." That's Mr. Database talking to
    Mr. Object. He was quite right, of course, but it confused me to think
    that way.

    It was as if my mechanic said, "Oh, you're trying to use this
    solenoid/starter assembly to initiate sequential explosions inside your

    cylinders with the aid of these spark plugs." To which I would say,
    "Uh, I just want to start my car." (As it happens, I really don't know
    much about cars or engines. That's a hardware problem.)

    So Mr. Database says, "Let's implement one-to-many also." (And he may
    have done others also, I don't have a KB install in front of me.)

    And my reaction is, well, OK, fine. But first of all, I don't
    personally
    see a need for it. (Of course, I might discover a need next week.)

    Second of all, I am not sure what analogy that would have in object
    terms. I suppose it would in effect be embedding an array where all the

    objects are objects derived from the rows of the child class. This
    bothers me a *little* because all the elements of the array would be
    of the same type. If you ever assign something else to that array,
    you'll
    get an error when you try to insert.

    Well, there's already some clash between Ruby and the database concept,

    because db fields have types, and attributes (as variables) don't have
    types. But this seemed like going a step farther to me -- heightening
    the clash by creating an array that has to be homogeneous, like a
    Pascal array.

    Third of all, if you start to have "one-to-one" and "one-to-many" links

    and such, you start having to distinguish between them. This makes
    table
    instantiation, even in the default case, just a tiny bit more
    difficult.
    It's creeping complexity. It's very small, but it adds up (and
    sometimes
    multiplies if you're not careful, the way probabilities multiply).

    See, there is a sort of "conservation of complexity" in any system. If
    I knew more information theory, I could express it better.

    Take data compression as an example. I can write a simple, dumb
    compression program that will compress most text by a factor of 2 or
    better. But that's not very good. An extremely complex algorithm (a
    much
    better one, that is) might compress by a factor of 10 or more.

    But the net information is the same, don't you see? We have moved the
    information from the data into the program. We have a very high-entropy

    resultant data file and a very low-entropy program. I have increased
    the
    data's entropy at the cost of increasing the entropy of the software.
    (My freezer keeps things very cold, but there is hot air coming out the

    back of the fridge.)

    I can compress the Declaration of Independence into a single byte with
    a
    sophisticated enough program, like the one shown here in part:

    if text == 'a'
    puts "When in the course of human events, it becomes necessary"
    # lines omitted
    puts "our lives, our fortunes, and our sacred honor."
    end

    You think I'm kidding, and I am. But I'm also not kidding at all.

    If I write a C program in 600 lines, I can probably write it in Ruby
    in 100 lines. Where did the complexity go? It left my program and went
    into the interpreter. That is where it belongs -- under the hood.
    Information hiding is how humans manage complexity. The concept of the
    black box is a greater human invention than the discovery of fire or
    the wheel.

    Now, suppose I specify a table with KirbyBase that has two simple
    fields,
    an integer and a string. We do it something like this (I probably am
    forgetting the method name):

    create_table:)mytablename,
    :alpha, :Integer,
    :beta, :String)

    Fine and dandy, nice and simple.

    Now suppose we add another field -- I'll abandon the Greek alphabet and

    call it "boss" which will be a Person object.

    In an absolutely perfect world, this would be "just another type." The
    software would read my mind and do exactly the right thing, and all I
    would type is:

    create_table:)mytablename,
    :alpha, :Integer,
    :beta, :String,
    :boss, :person)

    But this leaves some unanswered questions. Here are the questions and
    my
    answers -- pardon me for personifying the database software:

    1. "What table will I get this 'person' stuff from?" (Just derive the

    table name from the class name.)
    2. "What field in the child table will I use as a key?" (Hmm, maybe
    I'll
    have to tell you this one. It might be cool to be able to
    designate a
    key field, though.)
    3. "What type is that key field?" (Given the name, you can find it in
    the
    child table's information.)
    4. "What if Person itself is another complex object?" (Relax, just
    apply
    the same algorithm recursively. Worst that can happen is there is
    cyclic data, you'll go into an infinite loop, and I'll have to
    kill you.)

    Now, Jamey's first attempt at this had me writing code in the
    MYtablename#kb_create method, calling a method named one_to_one_link or
    some
    such. It felt very manual to me, like I was hotwiring my car.

    "What's the big deal?" says the mechanic. "All you do is, you grab
    these two
    wires, not these two, and touch them together for a little while, not
    too long,
    and..." And I reply: "I don't want to reach for the wires and grab
    them, I
    don't want to memorize the colors, I don't want to estimate the time
    interval,
    and I don't want to see wires dangling. Keep that under the hood."

    In one iteration, perhaps not the present one, a one-to-many
    relationship was
    stored inside its parent object as a KBResultSet. Ugly to me. If we
    must have
    one-to-many, let it be just an array. I don't want my choice of
    database to
    intrude into my objects any more than necessary. Given the right glue,
    *any*
    database should be usable for my objects. KirbyBase is implementing
    this glue
    pretty well so far, INSIDE the db software where it belongs.

    In the one-to-one case (present iteration), the type information is
    specified
    as an array. This was my suggestion, and in general I like it. But it
    is too
    complex. We may not reach the ideal shown above, but let's strive
    toward it.

    When I have Jamey's email in front of me, I'll tell you exactly what I
    mean.

    I was also disturbed a little to see that the class had to inherit from
    a KB
    class (I forget which one). It's hard to articulate why this bothers
    me. It's
    one more thing to remember, one more thing to do, and it's not a
    totally clean
    separation.

    Also, a word or two about the kb_create method (called automatically
    when a row
    is retrieved, to turn it into an object). In a perfect world, we should

    "normally" not have to define one at all. I'm thinking of ways to make
    it
    usually unnecessary. (In the case of "calculated fields," this might be
    the
    very best place to put them, however.)

    Hope this helps clarify things a little.

    And I'm glad to see this discussion happening in public, just in case I
    give
    Jamey some really stupid advice. :) I'd hate to persuade him into a bad
    design.



    Cheers,
    Hal
    , Sep 9, 2005
    #3
  4. Jamey Cribbs Guest

    wrote:

    >As I said, I'm an Object Guy and Jamey is a Database Guy. What does
    >that mean?
    >
    >
    >

    Sometimes it means we are like the "Odd Couple". Hey, which one of us
    is Felix?

    >I was working on an app and using KirbyBase. Because of the work Jamey
    >had done recently, creating objects from the database records was much
    >easier.
    >
    >But I noticed something. My fields were all simple types. (After all,
    >that's how databases work.) But I was taking my smaller objects and
    >using them to build bigger objects. In most cases, I was storing a key
    >into another table. So I would look up a record, and four of its fields
    >
    >would actually be keys into other tables. I'd then look up those four.
    >I'd then embed my four little objects inside an object corresponding to
    >
    >the original row.
    >
    >I had a feeling that I was doing too much work, that some of this could
    >
    >be done for me.
    >
    >My thoughts were like this: OK, we have primitive types such as integer
    >
    >and string. From OOP, I have a habit of thinking of classes as abstract
    >
    >types (see Bertrand Meyer -- I think).
    >
    >So if I want an object to have a member which is (e.g.) a Person, why
    >can't I treat Person just like String and Integer?
    >
    >In Ruby, we don't think of variables or attributes as being typed. I
    >make an exception in the case of retrieving objects from databases,
    >because I am very used to the idea of fields having types. (Although
    >someday I will comment on that also.)
    >
    >After all, even in Ruby, we often think to ourselves, "This member
    >will be a string" -- although if we are not careful, we might assign
    >any other thing to it. But I won't go off on too much of a tangent
    >here.
    >
    >So here I am. I'm thinking: Treat simple types (simple fields) the way
    >we already do. We store a type for each field. Let's store the complex
    >types the same way... but in the actual table, just store a key into
    >another table.
    >
    >That requires the table name and key field name to be specified
    >somehow,
    >of course. My take: Let's get slightly railsy and assume the class name
    >
    >lowercased is the table name (e.g. Person => person.tbl). That means we
    >
    >
    >

    Only problem with assuming this is that if the person table does not
    have a custom record class defined (default is a Struct), this won't
    work. I'll show you an example from my beta below to show you how I
    ended up working it.

    >only have to specify the field name explicitly (and I've been thinking
    >of a way to eliminate that also, by optionally establishing a known
    >"key field" for a table).
    >
    >

    Hal, I considered this, but, again, putting on my "Database Guy" hat, I
    thought, "What if there is more than one table that wants to link into
    this table? And what if this other table wants to use a different "key
    field" to perform that link?"

    >I was thinking "composite objects." I was thinking "embedding simpler
    >objects inside more complex ones." I was thinking "this is how I can
    >easily and transparently marshal my objects."
    >
    >When I mentioned this to Jamey, he said in effect, "Oh, you want one-
    >to-one links between database tables." That's Mr. Database talking to
    >Mr. Object. He was quite right, of course, but it confused me to think
    >that way.
    >
    >It was as if my mechanic said, "Oh, you're trying to use this
    >solenoid/starter assembly to initiate sequential explosions inside your
    >
    >cylinders with the aid of these spark plugs." To which I would say,
    >"Uh, I just want to start my car." (As it happens, I really don't know
    >much about cars or engines. That's a hardware problem.)
    >
    >So Mr. Database says, "Let's implement one-to-many also." (And he may
    >have done others also, I don't have a KB install in front of me.)
    >
    >

    Hal, I don't know if you have had a chance to take a look at the beta
    yet, but I basically tried to implement a uniform way to specify
    one-to-one links, one-to-many links, and calculated fields in the
    create_table method.

    >And my reaction is, well, OK, fine. But first of all, I don't
    >personally
    >see a need for it. (Of course, I might discover a need next week.)
    >
    >Second of all, I am not sure what analogy that would have in object
    >terms. I suppose it would in effect be embedding an array where all the
    >
    >objects are objects derived from the rows of the child class. This
    >bothers me a *little* because all the elements of the array would be
    >of the same type. If you ever assign something else to that array,
    >you'll
    >get an error when you try to insert.
    >
    >

    As a "Database Guy", I have a hard time understanding why this is a big
    issue. First of all, we aren't really "embedding" an array into the
    linked field. This field simply holds a reference to a KBResultSet
    instance, which is just a sub-classed Array with some extra attributes.
    In fact, the result of every #select in KirbyBase is an instance of
    KBResultSet. So, if you are link the Order.detail_items field to the
    Order_Items table, the Order.detail_items field for a particular Order
    record is going to hold a KBResultSet (i.e. Array) of all records from
    the Order_Items table that belong to that Order table.

    >Well, there's already some clash between Ruby and the database concept,
    >
    >because db fields have types, and attributes (as variables) don't have
    >types. But this seemed like going a step farther to me -- heightening
    >the clash by creating an array that has to be homogeneous, like a
    >Pascal array.
    >
    >
    >

    But that array is holding table records, just like the result of any
    #select. If you object to this array being a KBResultSet instance, it
    would seem like you would object to the fact that the select method also
    returns a KBResultSet.

    >Third of all, if you start to have "one-to-one" and "one-to-many" links
    >
    >and such, you start having to distinguish between them. This makes
    >table
    >instantiation, even in the default case, just a tiny bit more
    >difficult.
    >It's creeping complexity. It's very small, but it adds up (and
    >sometimes
    >multiplies if you're not careful, the way probabilities multiply).
    >
    >

    True, but the flip side is, if you don't allow for specifying different
    types of links, you paint yourself into a corner down the road *if* you
    decide to add additional link types.

    >See, there is a sort of "conservation of complexity" in any system. If
    >I knew more information theory, I could express it better.
    >
    >If I write a C program in 600 lines, I can probably write it in Ruby
    >in 100 lines. Where did the complexity go? It left my program and went
    >into the interpreter. That is where it belongs -- under the hood.
    >Information hiding is how humans manage complexity. The concept of the
    >black box is a greater human invention than the discovery of fire or
    >the wheel.
    >
    >
    >

    I agree completely. My first couple of attempts at adding more
    complexity to KirbyBase did not honor this concept. I had the user
    having to type too much code to tell KirbyBase how to define links,
    calculated fields, etc. Hal and I went back and forth, but I finally
    "got" what he was saying about this.

    >Now, suppose I specify a table with KirbyBase that has two simple
    >fields,
    >an integer and a string. We do it something like this (I probably am
    >forgetting the method name):
    >
    > create_table:)mytablename,
    > :alpha, :Integer,
    > :beta, :String)
    >
    >Fine and dandy, nice and simple.
    >
    >Now suppose we add another field -- I'll abandon the Greek alphabet and
    >
    >call it "boss" which will be a Person object.
    >
    >In an absolutely perfect world, this would be "just another type." The
    >software would read my mind and do exactly the right thing, and all I
    >would type is:
    >
    > create_table:)mytablename,
    > :alpha, :Integer,
    > :beta, :String,
    > :boss, :person)
    >
    >But this leaves some unanswered questions. Here are the questions and
    >my
    >answers -- pardon me for personifying the database software:
    >
    > 1. "What table will I get this 'person' stuff from?" (Just derive the
    >
    > table name from the class name.)
    >
    >

    What if they did not designate a class for the table, but let it default
    to Struct?

    > 2. "What field in the child table will I use as a key?" (Hmm, maybe
    >I'll
    > have to tell you this one. It might be cool to be able to
    >designate a
    > key field, though.)
    >
    >

    See my comments on key fields above.

    > 3. "What type is that key field?" (Given the name, you can find it in
    >the
    > child table's information.)
    >
    >

    True, but what if they have not created the Person table yet? How does
    KirbyBase find the type? If I have KirbyBase wait till runtime to find
    the type from the child table, now I have to have KirbyBase open the
    child table everytime it wants to get the type for the boss field, like,
    for example, when it needs to check that the user is entering the proper
    field type during a #insert.

    > 4. "What if Person itself is another complex object?" (Relax, just
    >apply
    > the same algorithm recursively. Worst that can happen is there is
    > cyclic data, you'll go into an infinite loop, and I'll have to
    >kill you.)
    >
    >

    Ok, so how did I solve this problem. Well, I tried to find a solution
    that was as simple for the user as possible, but left enough room for
    further expansion and for the unforseen (see my comments on "key" fields
    above). So, here is how you would specify the link between the :boss
    field and the :person table in the beta:

    create_table:)mytablename,
    :alpha, :Integer,
    :beta, :String,
    :boss, { :DataType => :String, :Link => [:person, :person_id] })

    This simply says, make a link between the value found in the boss field
    to the person_id field in the person table. It specifies the field type
    for boss :)String) and it tells which field to link to :)person_id)
    within the :person table, therefore we don't have to specify a key field
    in the :person table. It's a little more work, but, imo, not much, and
    you only have to do this once, when you create the table. After that,
    KirbyBase handles everything for you automatically.

    >Now, Jamey's first attempt at this had me writing code in the
    >MYtablename#kb_create method, calling a method named one_to_one_link or
    >some
    >such. It felt very manual to me, like I was hotwiring my car.
    >
    >
    >

    True. What seemed like a good idea at the time, because I felt like it
    gave total control of the "guts" to the user, turned out to be too
    cumbersome for the user. Hal finally got me to see this.

    >"What's the big deal?" says the mechanic. "All you do is, you grab
    >these two
    >wires, not these two, and touch them together for a little while, not
    >too long,
    >and..." And I reply: "I don't want to reach for the wires and grab
    >them, I
    >don't want to memorize the colors, I don't want to estimate the time
    >interval,
    >and I don't want to see wires dangling. Keep that under the hood."
    >
    >In one iteration, perhaps not the present one, a one-to-many
    >relationship was
    >stored inside its parent object as a KBResultSet. Ugly to me. If we
    >must have
    >one-to-many, let it be just an array. I don't want my choice of
    >database to
    >intrude into my objects any more than necessary. Given the right glue,
    >*any*
    >database should be usable for my objects. KirbyBase is implementing
    >this glue
    >pretty well so far, INSIDE the db software where it belongs.
    >
    >In the one-to-one case (present iteration), the type information is
    >specified
    >as an array. This was my suggestion, and in general I like it. But it
    >is too
    >complex. We may not reach the ideal shown above, but let's strive
    >toward it.
    >
    >

    Again, Hal may not have yet seen the examples in the beta of the new
    version yet. If you take a look at the example directory in the beta
    distribution, I have tried to give a good example of one-to-one links
    (link_test directory), one-to-many links (link_many_test directory),
    calculated fields (calculated_test directory), etc.

    Of course, Hal may look at those examples and still not like them. I'm
    interested in hearing his feedback, and everyone else's feedback on the
    beta. I've tried to strike a good balance between ease of use for the
    user and allowing for future functionality, but I'm sure when people
    look at the beta examples, they are going to have lots of great ideas
    for improvement.

    >When I have Jamey's email in front of me, I'll tell you exactly what I
    >mean.
    >
    >I was also disturbed a little to see that the class had to inherit from
    >a KB
    >class (I forget which one). It's hard to articulate why this bothers
    >me. It's
    >one more thing to remember, one more thing to do, and it's not a
    >totally clean
    >separation.
    >
    >

    I think I did away with this in the beta. You are right, that wasn't a
    good idea.

    >Also, a word or two about the kb_create method (called automatically
    >when a row
    >is retrieved, to turn it into an object). In a perfect world, we should
    >
    >"normally" not have to define one at all. I'm thinking of ways to make
    >it
    >usually unnecessary. (In the case of "calculated fields," this might be
    >the
    >very best place to put them, however.)
    >
    >

    Yep. My implementation in the beta means you don't have to use the
    kb_create method to specify link fields, calculated fields, or any of
    the new functionality. You can specify it all as arguments to the
    create_table method.

    >Hope this helps clarify things a little.
    >
    >And I'm glad to see this discussion happening in public, just in case I
    >give
    >Jamey some really stupid advice. :) I'd hate to persuade him into a bad
    >design.
    >
    >
    >

    I'm glad this discussion went public also. Prior to this, Hal was my
    only feedback person for the new features and I think I was badgering
    him to death. :)

    Well, if anyone is still reading this far, thanks!

    Jamey
    Jamey Cribbs, Sep 10, 2005
    #4
  5. Hal Fulton Guest

    Jamey Cribbs wrote:
    > wrote:
    >
    >> As I said, I'm an Object Guy and Jamey is a Database Guy. What does
    >> that mean?
    >>

    > Sometimes it means we are like the "Odd Couple". Hey, which one of us
    > is Felix?


    I'm Felix. :) No question about it.

    >>

    > Hal, I considered this, but, again, putting on my "Database Guy" hat, I
    > thought, "What if there is more than one table that wants to link into
    > this table? And what if this other table wants to use a different "key
    > field" to perform that link?"


    Good point. Let's let other people weigh in here.

    My gut reaction is: Fine, allow other tables to link via other fields, but
    let me use the default when I need/want to.

    >>

    > Hal, I don't know if you have had a chance to take a look at the beta
    > yet, but I basically tried to implement a uniform way to specify
    > one-to-one links, one-to-many links, and calculated fields in the
    > create_table method.


    That's what I thought... I'll have to play with it some. Hopefully
    very soon.

    >> And my reaction is, well, OK, fine. But first of all, I don't
    >> personally
    >> see a need for it. (Of course, I might discover a need next week.)
    >>
    >> Second of all, I am not sure what analogy that would have in object
    >> terms. I suppose it would in effect be embedding an array where all the
    >>
    >> objects are objects derived from the rows of the child class. This
    >> bothers me a *little* because all the elements of the array would be
    >> of the same type. If you ever assign something else to that array,
    >> you'll
    >> get an error when you try to insert.
    >>
    >>

    > As a "Database Guy", I have a hard time understanding why this is a big
    > issue. First of all, we aren't really "embedding" an array into the
    > linked field.


    No, I still think you are. Given, of course, the fact that all attributes
    contain references instead of actually "containing" the object. But that
    is beside the point.

    > This field simply holds a reference to a KBResultSet
    > instance, which is just a sub-classed Array with some extra attributes.
    > In fact, the result of every #select in KirbyBase is an instance of
    > KBResultSet. So, if you are link the Order.detail_items field to the
    > Order_Items table, the Order.detail_items field for a particular Order
    > record is going to hold a KBResultSet (i.e. Array) of all records from
    > the Order_Items table that belong to that Order table.


    If KBResultSet is an array, then we are in fact embedding an array.

    But maybe it is the word "embed" that you are objecting to. "Holds a
    reference to" is technically more correct, of course. But even an Array
    is only a collection of references -- when I say that an array contains
    the string "Hello", that is technically wrong. It contains a reference
    to the string "Hello" -- but that is mere nitpicking to me.

    I had forgot that #select always returned KBResultSet, probably because
    I always treat the result as an array (which it is, but through
    inheritance).

    Suppose I have an object with a "widgets" field. If I created an object
    (not originating in the db) and then tried to store it, would the widgets
    attribute have to be a KBResultSet in advance? Or no? If it did, I would
    find that unpleasant.

    >> Well, there's already some clash between Ruby and the database concept,
    >>
    >> because db fields have types, and attributes (as variables) don't have
    >> types. But this seemed like going a step farther to me -- heightening
    >> the clash by creating an array that has to be homogeneous, like a
    >> Pascal array.
    >>

    > But that array is holding table records, just like the result of any
    > #select. If you object to this array being a KBResultSet instance, it
    > would seem like you would object to the fact that the select method also
    > returns a KBResultSet.


    Actually, I didn't object because I forgot. :)

    It's different getting stuff *from* the database. I only deal with the
    objects in the collection, and they do indeed come back as Foobar objects.

    But I would never design an object by saying, "I'll give it this field,
    which will normally be a string, and this one, which will normally be
    a KBResultSet."

    >> Third of all, if you start to have "one-to-one" and "one-to-many" links
    >>
    >> and such, you start having to distinguish between them. This makes
    >> table
    >> instantiation, even in the default case, just a tiny bit more
    >> difficult.
    >> It's creeping complexity. It's very small, but it adds up (and
    >> sometimes
    >> multiplies if you're not careful, the way probabilities multiply).
    >>
    >>

    > True, but the flip side is, if you don't allow for specifying different
    > types of links, you paint yourself into a corner down the road *if* you
    > decide to add additional link types.


    I guess what I would like is a simple notation for the common, simple
    operations; and a complex notation (if necessary) for more complex, rare
    operations.

    I don't want to complicate 100% of the notation because 1% of the time
    somebody else is going to need that feature.

    I'm still trying to figure out a way to say: "If there's no link type
    specified, it's one-to-one. And if there's no field specified, use the
    key field on the child table."

    But your point is very well taken that there should be the *capability*
    of other types of links.

    >> See, there is a sort of "conservation of complexity" in any system. If
    >> I knew more information theory, I could express it better.
    >>
    >> If I write a C program in 600 lines, I can probably write it in Ruby
    >> in 100 lines. Where did the complexity go? It left my program and went
    >> into the interpreter. That is where it belongs -- under the hood.
    >> Information hiding is how humans manage complexity. The concept of the
    >> black box is a greater human invention than the discovery of fire or
    >> the wheel.
    >>

    > I agree completely. My first couple of attempts at adding more
    > complexity to KirbyBase did not honor this concept. I had the user
    > having to type too much code to tell KirbyBase how to define links,
    > calculated fields, etc. Hal and I went back and forth, but I finally
    > "got" what he was saying about this.


    There's always more than one way to do it.

    >
    >> 3. "What type is that key field?" (Given the name, you can find it in
    >> the
    >> child table's information.)
    >>

    > True, but what if they have not created the Person table yet? How does
    > KirbyBase find the type? If I have KirbyBase wait till runtime to find
    > the type from the child table, now I have to have KirbyBase open the
    > child table everytime it wants to get the type for the boss field, like,
    > for example, when it needs to check that the user is entering the proper
    > field type during a #insert.


    I guess that would be a big problem, one I hadn't thought of at all.

    >
    >> 4. "What if Person itself is another complex object?" (Relax, just
    >> apply
    >> the same algorithm recursively. Worst that can happen is there is
    >> cyclic data, you'll go into an infinite loop, and I'll have to
    >> kill you.)
    >>
    >>

    > Ok, so how did I solve this problem. Well, I tried to find a solution
    > that was as simple for the user as possible, but left enough room for
    > further expansion and for the unforseen (see my comments on "key" fields
    > above). So, here is how you would specify the link between the :boss
    > field and the :person table in the beta:
    >
    > create_table:)mytablename,
    > :alpha, :Integer,
    > :beta, :String,
    > :boss, { :DataType => :String, :Link => [:person, :person_id] })
    >
    > This simply says, make a link between the value found in the boss field
    > to the person_id field in the person table. It specifies the field type
    > for boss :)String) and it tells which field to link to :)person_id)
    > within the :person table, therefore we don't have to specify a key field
    > in the :person table. It's a little more work, but, imo, not much, and
    > you only have to do this once, when you create the table. After that,
    > KirbyBase handles everything for you automatically.


    I'm not saying this is "bad." We're far ahead of things like DBM and Marshal
    and such.

    I'm just saying that (especially for the common case) THIS:

    :boss, { :DataType => :String, :Link => [:person, :person_id] }

    is a little too far from

    :boss, :person

    I'm talking subtlety here. I'm talking the difference between having to
    look up syntax "sometimes" or "never."

    This is just me. Everybody's mind works differently. We all have different
    sets of things that we always forget and have to look up.

    When I shut my eyes, I can't even remember what the long version looks like.
    I'd have to sit and scribble and figure it out.

    If I were coding, I would run through a thought process sort of like this:

    "OK, field name followed by type. Type, let's see, that's specified as a
    hash. And one element tells the data type. Something like
    "datatype" => :String. Wait, is that key a string or a symbol? I think
    it's a symbol. Is it :datatype or :Datatype? No, wait, I think it's
    :DataType. OK, and the other part of the hash tells about the kind of thing
    I'm storing. That key is a symbol too. Or are they both strings? No, I'm
    pretty sure they're both symbols. This one is some kind of database term,
    what is it, :connect or :join or something? No, wait, I think it's
    :eek:ne_to_one. No, it's :link_one_to_one. No, no, that's wrong, it's just
    :link. But wait, it's capitalized, isn't it. OK, so that is associated
    with some kind of array. Two elements, I think? No, it must be three. It's
    the table name and the field name and the field type. No, that can't be
    right. It's just the table name and the field name. Or does the field name
    come first? No, I'm sure the table name comes first. OK, here we go."

    If I were doing it the other way, I would think: "OK, we have a symbol
    for the field name, followed by a symbol for its type."

    Granted there might be times I would need something complex enough to
    justify the extra work. But (for me) 99% of the time it would be waste.

    >> Now, Jamey's first attempt at this had me writing code in the
    >> MYtablename#kb_create method, calling a method named one_to_one_link or
    >> some
    >> such. It felt very manual to me, like I was hotwiring my car.
    >>

    > True. What seemed like a good idea at the time, because I felt like it
    > gave total control of the "guts" to the user, turned out to be too
    > cumbersome for the user. Hal finally got me to see this.


    Very much a matter of opinion where to draw the line. Again, I do favor
    "total control" (as in "total flexibility") -- but I think that most
    of the time, you shouldn't have to exercise that total control.

    >>

    > Again, Hal may not have yet seen the examples in the beta of the new
    > version yet. If you take a look at the example directory in the beta
    > distribution, I have tried to give a good example of one-to-one links
    > (link_test directory), one-to-many links (link_many_test directory),
    > calculated fields (calculated_test directory), etc.


    I should study them before mouthing off any more.

    > Of course, Hal may look at those examples and still not like them. I'm
    > interested in hearing his feedback, and everyone else's feedback on the
    > beta. I've tried to strike a good balance between ease of use for the
    > user and allowing for future functionality, but I'm sure when people
    > look at the beta examples, they are going to have lots of great ideas
    > for improvement.


    Ultimately it's your software. It's not a democracy, it's a monarchy. :)

    I appreciate the chance to give feedback to you. We all give feedback to
    Matz, too, but he properly ignores most of it. Imagine how Ruby would
    look if even HALF the RCRs were accepted.

    >> Also, a word or two about the kb_create method (called automatically
    >> when a row
    >> is retrieved, to turn it into an object). In a perfect world, we should
    >>
    >> "normally" not have to define one at all. I'm thinking of ways to make
    >> it
    >> usually unnecessary. (In the case of "calculated fields," this might be
    >> the
    >> very best place to put them, however.)
    >>

    > Yep. My implementation in the beta means you don't have to use the
    > kb_create method to specify link fields, calculated fields, or any of
    > the new functionality. You can specify it all as arguments to the
    > create_table method.
    >
    >> Hope this helps clarify things a little.
    >>
    >> And I'm glad to see this discussion happening in public, just in case I
    >> give
    >> Jamey some really stupid advice. :) I'd hate to persuade him into a bad
    >> design.
    >>

    > I'm glad this discussion went public also. Prior to this, Hal was my
    > only feedback person for the new features and I think I was badgering
    > him to death. :)


    No, not at all, quite the reverse. Most of the time if I email an author
    and said, "This feature would be nice," he'll say, "Yeah, write up a
    proposal and send me an email. I'll open it six months from now and
    ignore it."

    But you -- when I say, "This feature would be nice," I wait 24-48 hours
    and BOOM, it shows up in my inbox.

    My only fears were 1) that I was nagging you to death, being the Feature
    Creep, and 2) that I might be nudging you into wrong design decisions.

    > Well, if anyone is still reading this far, thanks!


    And thanks from me too.

    This is a useful tool already. It's gone from being a manual screwdriver
    to being a powered one. Now we are only haggling over the shape of the
    rubberized nubs on the handle. :)


    Cheers,
    Hal
    Hal Fulton, Sep 10, 2005
    #5
  6. Jamey Cribbs Guest

    Hal Fulton wrote:

    > Jamey Cribbs wrote:
    >
    >> Hal, I considered this, but, again, putting on my "Database Guy" hat,
    >> I thought, "What if there is more than one table that wants to link
    >> into this table? And what if this other table wants to use a
    >> different "key field" to perform that link?"

    >
    >
    > Good point. Let's let other people weigh in here.
    >
    > My gut reaction is: Fine, allow other tables to link via other fields,
    > but
    > let me use the default when I need/want to.
    >

    I think the light bulb came on over my head. :)

    See my comments near the bottom.

    > It's different getting stuff *from* the database. I only deal with the
    > objects in the collection, and they do indeed come back as Foobar
    > objects.
    >
    > But I would never design an object by saying, "I'll give it this field,
    > which will normally be a string, and this one, which will normally be
    > a KBResultSet."
    >

    Ok, that makes sense. But, in essence, when you have a field that is
    really a one-to-many link to another table, all you are really doing is
    just getting stuff *from* the database, because, behind the scenes, all
    KirbyBase is doing is doing a select against that child table.

    You will never be *assigning* any value to that one-to-many link,
    because it is just a virtual field. There will never be a "real" value
    stored in the table for that field. It is always just going to be a
    virtual field that, when you ask for it's value, goes out and does a
    select against the child table and returns the selected records.

    >
    > I guess what I would like is a simple notation for the common, simple
    > operations; and a complex notation (if necessary) for more complex, rare
    > operations.
    >
    > I don't want to complicate 100% of the notation because 1% of the time
    > somebody else is going to need that feature.
    >
    > I'm still trying to figure out a way to say: "If there's no link type
    > specified, it's one-to-one. And if there's no field specified, use the
    > key field on the child table."
    >

    I think I get what you are saying. If the field definition looks like this:

    :manager, :person

    I could have KirbyBase *assume* the following:

    1. You want :manager to reference a record (object) in the :person table.
    2. The field in :person that :manager should equal will be the :person
    table's key field (designated in the definition of the :person table).
    3. The data type of :manager will be the same as the data type of the
    key field of the :person table, so go look up that up.

    This would be the default behavior. If the user wanted to override
    KirbyBase's assumptions, they could do that by being more verbose in the
    create_table method.

    Jamey

    Confidentiality Notice: This email message, including any attachments, is for the sole use of the intended recipient(s) and may contain confidential and/or privileged information. If you are not the intended recipient(s), you are hereby notified that any dissemination, unauthorized review, use, disclosure or distribution of this email and any materials contained in any attachments is prohibited. If you receive this message in error, or are not the intended recipient(s), please immediately notify the sender by email and destroy all copies of the original message, including attachments.
    Jamey Cribbs, Sep 12, 2005
    #6
  7. Guest

    Jamey Cribbs wrote:
    >
    > > It's different getting stuff *from* the database. I only deal with the
    > > objects in the collection, and they do indeed come back as Foobar
    > > objects.
    > >
    > > But I would never design an object by saying, "I'll give it this field,
    > > which will normally be a string, and this one, which will normally be
    > > a KBResultSet."
    > >

    > Ok, that makes sense. But, in essence, when you have a field that is
    > really a one-to-many link to another table, all you are really doing is
    > just getting stuff *from* the database, because, behind the scenes, all
    > KirbyBase is doing is doing a select against that child table.
    >
    > You will never be *assigning* any value to that one-to-many link,
    > because it is just a virtual field. There will never be a "real" value
    > stored in the table for that field. It is always just going to be a
    > virtual field that, when you ask for it's value, goes out and does a
    > select against the child table and returns the selected records.


    That's very interesting, because I was assuming total symmetry
    between what I could get out of the database and what I could put in.

    I mean, sure, calculated fields are an exception. But I never thought
    of your one-to-many as just another calculated or virtual field.

    I guess I thought if I stuck five things in the array and did an
    insert of the parent object, it would make an entry in the parent
    table and five entries in the child table.

    If you look at Marshal or YAML, everything goes both ways. True,
    there are some things that can't be stored at all. But there is
    never any one-way storage.

    If one-to-many links are not symmetrical, that's the best reason
    of all I'll never use them.

    > >

    > I think I get what you are saying. If the field definition looks like this:
    >
    > :manager, :person
    >
    > I could have KirbyBase *assume* the following:
    >
    > 1. You want :manager to reference a record (object) in the :person table.
    > 2. The field in :person that :manager should equal will be the :person
    > table's key field (designated in the definition of the :person table).
    > 3. The data type of :manager will be the same as the data type of the
    > key field of the :person table, so go look up that up.
    >
    > This would be the default behavior. If the user wanted to override
    > KirbyBase's assumptions, they could do that by being more verbose in the
    > create_table method.
    >


    I think that's very close to my own way of thinking.

    I still wish others would express opinions. Is anybody else even
    reading
    this thread? If not, we could have this discussion in private. I have a

    feeling there might be two or three people on this list as smart as
    both of us put together.


    Cheers,
    Hal
    , Sep 12, 2005
    #7
  8. This is kind of off on a tangent, but has anyone ever considered
    making an ActiveRecord adapter for KirbyBase? It doesn't seem like it
    would be too hard. Would anyone be interested if I attempted this?
    Logan Capaldo, Sep 12, 2005
    #8
  9. Jamey Cribbs Guest

    wrote:

    >Jamey Cribbs wrote:
    >
    >
    >>>It's different getting stuff *from* the database. I only deal with the
    >>>objects in the collection, and they do indeed come back as Foobar
    >>>objects.
    >>>
    >>>But I would never design an object by saying, "I'll give it this field,
    >>>which will normally be a string, and this one, which will normally be
    >>>a KBResultSet."
    >>>
    >>>
    >>>

    >>Ok, that makes sense. But, in essence, when you have a field that is
    >>really a one-to-many link to another table, all you are really doing is
    >>just getting stuff *from* the database, because, behind the scenes, all
    >>KirbyBase is doing is doing a select against that child table.
    >>
    >>You will never be *assigning* any value to that one-to-many link,
    >>because it is just a virtual field. There will never be a "real" value
    >>stored in the table for that field. It is always just going to be a
    >>virtual field that, when you ask for it's value, goes out and does a
    >>select against the child table and returns the selected records.
    >>
    >>

    >
    >That's very interesting, because I was assuming total symmetry
    >between what I could get out of the database and what I could put in.
    >
    >I mean, sure, calculated fields are an exception. But I never thought
    >of your one-to-many as just another calculated or virtual field.
    >
    >
    >

    <Jamey dons Database Guy hat>

    Well, I view it as analogous to doing a join in SQL. To get the data
    from a one-to-many link in SQL you would normally do a JOIN in your
    SELECT statement. This gives you a result set with the columns from
    both tables showing up on each record. The data is now no longer
    normalized, therefore it no longer has the same structure as either of
    the original tables.

    That's kind of how I view a #select in KirbyBase that has a one-to-many
    link in it. I actually like it bettern than a JOIN in SQL because the
    data is still normalized, but I don't look at it as something that you
    could modify and then turn around and update the database with.

    <Jamey removes Database Guy hat>

    >I guess I thought if I stuck five things in the array and did an
    >insert of the parent object, it would make an entry in the parent
    >table and five entries in the child table.
    >
    >
    >

    I definitely see your point. Again, I was basing the one-to-many link
    similarly to how SQL works. In SQL, you would not do it the way you
    just said. You would actually do an INSERT on the parent table, then 5
    INSERTS on the child table.

    Let me think about what you are saying. Maybe for the future...

    >If you look at Marshal or YAML, everything goes both ways. True,
    >there are some things that can't be stored at all. But there is
    >never any one-way storage.
    >
    >If one-to-many links are not symmetrical, that's the best reason
    >of all I'll never use them.
    >
    >

    Well, based on your previous comments about my proposed implementation
    of one-to-many links, I kind of figured you wouldn't be using them
    anytime soon! :)

    >I still wish others would express opinions. Is anybody else even
    >reading
    >this thread? If not, we could have this discussion in private. I have a
    >
    >feeling there might be two or three people on this list as smart as
    >both of us put together.
    >
    >

    I know. I can't believe others on this list don't find this discussion
    as exciting as I do! :)

    Jamey

    Confidentiality Notice: This email message, including any attachments, is for the sole use of the intended recipient(s) and may contain confidential and/or privileged information. If you are not the intended recipient(s), you are hereby notified that any dissemination, unauthorized review, use, disclosure or distribution of this email and any materials contained in any attachments is prohibited. If you receive this message in error, or are not the intended recipient(s), please immediately notify the sender by email and destroy all copies of the original message, including attachments.
    Jamey Cribbs, Sep 12, 2005
    #9
  10. Guest

    > <Jamey dons Database Guy hat>
    >
    > Well, I view it as analogous to doing a join in SQL.


    [snip]

    Yep, there's our disconnect. My "real job" requires me to use SQL,
    but even then I do as little as possible.

    > That's kind of how I view a #select in KirbyBase that has a one-to-many
    > link in it. I actually like it bettern than a JOIN in SQL because the
    > data is still normalized, but I don't look at it as something that you
    > could modify and then turn around and update the database with.


    I just want to store and retrieve objects. If I retrieve an object, I
    should be able to change it and store it back. Think YAML.

    In fact, the reason I don't use YAML is because of its lack of "high
    level" access (select and such), not because of its core model
    necessarily.

    In the past, I have made much use of DBM to store YAML'd strings. This
    is not so bad.

    But DBM suffers from a few deficiencies I've listed elsewhere.
    KirbyBase
    is much cooler.

    > >

    > I definitely see your point. Again, I was basing the one-to-many link
    > similarly to how SQL works. In SQL, you would not do it the way you
    > just said. You would actually do an INSERT on the parent table, then 5
    > INSERTS on the child table.
    >
    > Let me think about what you are saying. Maybe for the future...


    SQL is a standard, but to me it's old technology. It was trendy and
    cool in the 60s, but then so was the beehive hairdo.

    > >

    > Well, based on your previous comments about my proposed implementation
    > of one-to-many links, I kind of figured you wouldn't be using them
    > anytime soon! :)


    Haha! Well, there is a magic line that I am always looking for. It's
    the
    line which, when it is crossed, I start having to look things up
    instead
    of remembering them. So far, nearly all of KB is below that line (like
    nearly all of Ruby).

    Just one thing: The one-to-one relationship, is it round-trip or not??

    > >I still wish others would express opinions. Is anybody else even
    > >reading
    > >this thread? If not, we could have this discussion in private. I have a
    > >
    > >feeling there might be two or three people on this list as smart as
    > >both of us put together.
    > >
    > >

    > I know. I can't believe others on this list don't find this discussion
    > as exciting as I do! :)


    Maybe they have cable TV or something. :-D


    Cheers,
    Hal
    , Sep 12, 2005
    #10
  11. Guest

    It sounds interesting to me. Ask Jamey.

    Two questions:

    1. AR doesn't depend on SQL?
    2. Would this allow KB to be a backend db for Rails?


    Hal
    , Sep 12, 2005
    #11
  12. Jim Menard Guest

    On 9/12/05, <> wrote:

    > Maybe they have cable TV or something. :-D


    I've been following this thread with great interest. I just don't have
    anything cogent to add that hasn't yet been said.

    I use KirbyBase on a few small personal projects where a relational
    database would be overkill; not because the data isn't relational (it
    is, in one project), but because I'd rather have the data in ASCII
    than in a database. On those projects, data portability and
    editability is more important than relational...er...relationships.

    Jim
    --=20
    Jim Menard, ,
    http://www.io.com/~jimm
    Jim Menard, Sep 12, 2005
    #12
  13. Randy Kramer Guest

    On Monday 12 September 2005 04:11 pm, Jamey Cribbs wrote:
    > >If one-to-many links are not symmetrical, that's the best reason
    > >of all I'll never use them.


    There are (some) other people paying (some) attention.

    In a traditional relational database system, what goes in can come out, and
    I'm not sure that anyting different is being proposed here (but I may be
    confused).

    Aside: One-to-many links are inherently not symmetrical, and I don't know what
    is meant by storing something in the "one-to-many" link.

    The one to many link is typically accomplished by keys. If a one to many link
    exists, it is because a record in on table contains a key (to indicate
    linking) to another table wherein multiple records with the same key are
    allowed. Hence you have a record in one table that relates to (or can relate
    to) multiple records in the other table.

    Is there something different going on in KirbyBase?

    Randy Kramer
    Randy Kramer, Sep 12, 2005
    #13
  14. On Sep 12, 2005, at 1:46 PM, wrote:
    >>>

    >> I know. I can't believe others on this list don't find this
    >> discussion
    >> as exciting as I do! :)
    >>

    >
    > Maybe they have cable TV or something. :-D
    >
    >
    > Cheers,
    > Hal
    >
    >

    Guys-
    I am watching this thread with great interest. I don't have much
    to add at the moment but please keep it up.
    Cheers-
    -Ezra Zygmuntowicz
    Yakima Herald-Republic
    WebMaster
    509-577-7732
    Ezra Zygmuntowicz, Sep 12, 2005
    #14
  15. On 9/12/05, Jim Menard <> wrote:
    > On 9/12/05, <> wrote:
    >=20
    > > Maybe they have cable TV or something. :-D

    >=20
    > I've been following this thread with great interest. I just don't have
    > anything cogent to add that hasn't yet been said.


    Me too.

    Michel.
    Michel Martens, Sep 12, 2005
    #15
  16. On Sep 12, 2005, at 4:46 PM, wrote:

    > It sounds interesting to me. Ask Jamey.
    >
    > Two questions:
    >
    > 1. AR doesn't depend on SQL?
    > 2. Would this allow KB to be a backend db for Rails?
    >
    >
    > Hal
    >
    >
    >


    1. Maybe, maybe not. I get the feeling that it could probably be
    adapted with a bit of work. Might have to rewrite a lot of code in
    the process

    2. Maybe. It would depend on how full-featured the adapter was I
    suppose. I was thinking more along the lines of advantages of using
    ideas from the ActiveRecord impl. of ORM in KirbyBase, since ORM
    seems to be a lot of what you guys are talking about adding to
    KirbyBase.

    Perhaps I would not even write an activerecord adapter but a
    KirbyBase ORM modeled on the activerecord style.

    So in conclusion, maybe?
    Logan Capaldo, Sep 12, 2005
    #16
  17. Kirk Haines Guest

    On Monday 12 September 2005 1:36 pm, wrote:

    > I still wish others would express opinions. Is anybody else even
    > reading
    > this thread? If not, we could have this discussion in private. I have a


    I have been saving the mails and skimming them, hoping to come back and read
    them in depth later. Most of what you are talking about is ORM stuff, and
    the KirbyBase query model seems somewhat similar to the Kansas query model,
    so if nothing else, I'm hoping to catch sight of something useful to me, even
    if I get to everything too late to really participate in the discussion.


    Kirk Haines
    Kirk Haines, Sep 12, 2005
    #17
  18. Guest

    Randy Kramer wrote:
    > On Monday 12 September 2005 04:11 pm, Jamey Cribbs wrote:
    > > >If one-to-many links are not symmetrical, that's the best reason
    > > >of all I'll never use them.

    >
    > There are (some) other people paying (some) attention.
    >
    > In a traditional relational database system, what goes in can come out, and
    > I'm not sure that anyting different is being proposed here (but I may be
    > confused).


    Traditional relational databases can't return objects, which is
    why I'm not thinking solely in terms of traditional relational
    databases.

    > Aside: One-to-many links are inherently not symmetrical, and I don't know what
    > is meant by storing something in the "one-to-many" link.


    When you say it in those terms, it does sound nonsensical. That is
    why I don't speak in terms of links at all, and why it confuses me
    when others do.

    I know that one-to-many links are not symmetrical between tables.
    What I meant is that their behavior (IMO) should be symmetrical.
    If I can select a parent and trigger selects on the child
    automagically,
    then I should also be able to do an insert on the parent and trigger
    child inserts automagically.

    > The one to many link is typically accomplished by keys. If a one to many link
    > exists, it is because a record in on table contains a key (to indicate
    > linking) to another table wherein multiple records with the same key are
    > allowed. Hence you have a record in one table that relates to (or can relate
    > to) multiple records in the other table.
    >
    > Is there something different going on in KirbyBase?


    Yes and no. To me, the essence of what makes KirbyBase cool is:
    1. It has a Rubylike interface.
    2. It can handle objects (pretty much transparently).

    Implementation of point 1 is strong, but that of point 2 is less
    strong.


    In a nutshell, this is how my thinking has progressed:

    1. KB is good at fields with simple types. When I do a select, it
    returns
    me an object (e.g. a Foobar object) where the field names are simple
    accessors. Coolness. Life is good.

    2. However, many of my objects are more complex. Say I add a new field
    "boss" which is a Person. Hmm. The logical place to store this is in a
    table Person (or whatever).

    3. So I start to handle it manually. Every time I do a select and get
    a Foobar object, I then do a select on the table storing Person
    objects.
    Then I manually assign the second result to the proper field in the
    Foobar object. Likewise, when I create a Foobar object and I want to
    insert it, I have to do two manual inserts.

    4. No, no. There is enough knowledge in the system that the software
    could do this itself. I am doing the computer's job.

    5. So I tell Jamey, "I'd like to be able to handle objects that have
    attiributes that are not just integers or strings, but objects in
    their own right, with their own accessors." And he says, "Oh, you
    want one-to-one links." And I say, "Huh? I want what?"

    6. And he says, "If we implement one-to-one links, it makes sense
    to implement one-to-many." And I say, "Huh??"

    7. And I think: What would a one-to-many databasse relationship look
    like in object terms? So I decide it must correspond to an array
    inside my Foobar object. And it doesn't sound like something I would
    ever really use or see a need for. But to accommodate the case that
    I might use 3% of the time, the syntax for the case I use 97% of
    the time has to become five times nore complex. (Granted, once I
    get into it more deeply, I might be glad to have "one-to-many" and
    use it in ways I don't foresee now.)

    8. But #7 is almost beside the point. Here's an example.

    I'm using a,b,c for simple types such as integer or string, and
    alpha,beta,gamma for complex types such as Person or whatever.

    Foobar # Looks like...
    a,b,c # simple fields
    alpha # a Barbar object
    beta # a Bazz object

    Barbar # Looks like...
    d,e # simple
    gamma, # Bazz objects
    delta

    Bazz # Looks like...
    f,g # simple

    Now I have foo = Foobar.new(...) and I want to store foo.

    The traditional way would take FIVE insert operations. That is
    FIVE user-written lines of code.

    My way would take ONE line, ONE insert operation. You store foo,
    and in the process it stores alpha, which involves storing d,e, and
    gamma, which involves storing f and g.

    footab.insert(foo)

    In other words, the recursion is handled for you, rather than your
    having to manually recurse. Think of the way YAML handles recursion.
    What if every "more complex" data type required a separate dump
    call?

    Likewise, inserting and selecting should work the same way.

    bar = footab.select { condition_identifying_unique_object }[0]
    # Now bar.alpha.gamma.f is defined (among others)

    The other way would take FIVE selects and FIVE assignment statements,
    total of TEN lines of user-writtten code.

    Here I am replacing fifteen lines with two. In more complex situations,
    the difference would be greater.


    Hal
    , Sep 13, 2005
    #18
  19. Kevin Brown Guest

    On Monday 12 September 2005 17:06, wrote:
    > Randy Kramer wrote:
    > 7. And I think: What would a one-to-many databasse relationship look
    > like in object terms? So I decide it must correspond to an array
    > inside my Foobar object. And it doesn't sound like something I would
    > ever really use or see a need for. But to accommodate the case that
    > I might use 3% of the time, the syntax for the case I use 97% of
    > the time has to become five times nore complex. (Granted, once I
    > get into it more deeply, I might be glad to have "one-to-many" and
    > use it in ways I don't foresee now.)


    class moo
    def initialize
    @1 = Time.now
    @2 = Time.now
    end
    end

    moo.new

    Moo now contains many Time objects. Throw it at KirbyBase, and you want a one
    to many (which just means that one moo contains many time objects). There's
    no reason to have multiple Time tables (one for each instance) when they're
    the same fields, no? You're right, this would usually fall out of an array,
    and it's when you want one to many relationships implemented. This happens a
    LOT in the real world (at least in my programming style). Hope this helps
    clear up the 3% to 97% analogy. :)
    Kevin Brown, Sep 13, 2005
    #19
  20. Hal Fulton Guest

    Logan Capaldo wrote:
    >
    >
    > Perhaps I would not even write an activerecord adapter but a KirbyBase
    > ORM modeled on the activerecord style.
    >


    Perhaps... in fact, that might even be the key to my happiness.

    Maybe I'm tying to get Jamey to put stuff *into* KB that should
    really be an ORM wrapper *around* it.

    Thoughts? Logan, Jamey, others?


    Hal
    Hal Fulton, Sep 13, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jamey Cribbs

    ANNOUNCE: KirbyBase 1.3

    Jamey Cribbs, Aug 16, 2003, in forum: Python
    Replies:
    0
    Views:
    335
    Jamey Cribbs
    Aug 16, 2003
  2. Jamey Cribbs

    ANNOUNCE: KirbyBase 1.4

    Jamey Cribbs, Aug 27, 2003, in forum: Python
    Replies:
    0
    Views:
    294
    Jamey Cribbs
    Aug 27, 2003
  3. Jamey Cribbs

    ANNOUNCE: KirbyBase 1.5

    Jamey Cribbs, Sep 4, 2003, in forum: Python
    Replies:
    0
    Views:
    286
    Jamey Cribbs
    Sep 4, 2003
  4. Jamey Cribbs

    ANNOUNCE: KirbyBase 1.7

    Jamey Cribbs, Jan 30, 2005, in forum: Python
    Replies:
    3
    Views:
    367
    Paul McGuire
    Jan 31, 2005
  5. Jamey Cribbs
    Replies:
    0
    Views:
    332
    Jamey Cribbs
    Jan 31, 2005
Loading...

Share This Page