SitePoint Sponsor

User Tag List

Page 2 of 2 FirstFirst 12
Results 26 to 47 of 47
  1. #26
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I should think it has it's uses internally too. The API is quite powerful, and offers some portability not given if you just hardcode the queries into Description. Get a feeling for the possibilities at : http://db.apache.org/torque/criteria-howto.html

    What stopped you getting the test to work?
    I didn't try too hard. It did not run out-of-the-box so I gave up. I'll probably get back to it an a couple of days though.

    What is the overall project you are targeting with it? In-house you mention, but wouldn't you be tempted to take the code to production-level and release it as open-source ? It could work well as a lightweight alternative to something like propel. Plus it works under php4.

  2. #27
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Regarding portability, the SQL classes maintain that abstraction. I like the idea of adding a simpler Criteria for adding raw SQL for special types if that were needed. The system is not so much a SQL abstraction though, as an object database that sits on top of a DB. In that sense we control the possible searches to some extent. Criteria adds an extra layering so I think any switch to Criteria would be better if it were whole hearted. I don't really know though.

    Another option to the Criteria would be to provide a hook to allow the replacement of the Description class. Unfortunately everything is too entangled right now.

    Quote Originally Posted by kyberfabrikken
    What is the overall project you are targeting with it? In-house you mention, but wouldn't you be tempted to take the code to production-level and release it as open-source ? It could work well as a lightweight alternative to something like propel. Plus it works under php4.
    Our ambitions are purely in-house. We just don't have time to maintain an open source project (yet another in my case) and just released it so that people could pinch the ideas. I know of at least one project that is using the code as a starting point for their own system though.

    We will publicly release another version sometime next year once it has been battle tested. Peter, Mike and myself want to write an article on the differences between the Java environment and the PHP environment as we have developers that straddle that divide. The code would be used to illustrate that article, possibly for Dr. Dobbs or somesuch.

    I am afraid that's all we are hoping for . If all it ever did was influence Propel then that would be a success.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  3. #28
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The system is not so much a SQL abstraction though, as an object database that sits on top of a DB. In that sense we control the possible searches to some extent. Criteria adds an extra layering so I think any switch to Criteria would be better if it were whole hearted.
    I think you may be right about that, though I can't really comprehend the full image either.

    Another option to the Criteria would be to provide a hook to allow the replacement of the Description class. Unfortunately everything is too entangled right now.
    I suppose all that is needed is to make an interface for injecting raw SQL into the Description-class.

    Peter, Mike and myself want to write an article on the differences between the Java environment and the PHP environment as we have developers that straddle that divide.
    Would that be focused on data-access or more general ?

  4. #29
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by kyberfabrikken
    Would that be focused on data-access or more general?
    The trouble with articles is that you start writing one thing, but by the time you get to the last line you have written something else. So we don't know yet .

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  5. #30
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What does this line actually do ?
    PHP Code:
    $this->execute('set transaction isolation level serializable'); 
    Edit:


    hmm ... guess I could just read the documentation for MYSQL.
    Last edited by kyberfabrikken; Dec 16, 2004 at 10:02.

  6. #31
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    We have been discussing how to apply an IdentityMap to provide a per-object-cache. I have been toying a bit with a query-level cache too.
    The idea is that you may fire off several identical queries during the same request. This ofcause depends alot on the context, you use the library in. If you pull big amounts of data, it's not benificiary, since the results will stay in-memory until the request ends, but under other circumstances it could save a few redundant queries.
    I found use for such an option in relation to hieraical data, and with composite views witch pull from the same datasource.
    I'm a bit in doubt whether this is a good way to solve such issues, or if a better IdentityMap could make it redundant - Any thoughts on that ?

    QueryBuffer.php
    PHP Code:
    class QueryBuffer
    {
        var 
    $connection;
        var 
    $queryBuffer;

        function 
    QueryBuffer(&$connection)
        {
            
    $this->connection =& $connection;
            
    $this->queryBuffer = Array();
        }

        function & 
    getConnection()
        {
            return 
    $this->connection;
        }

        
    /**
          * Clears the buffer
          */
        
    function clearBuffer()
        {
            
    $this->queryBuffer = Array();
        } 
    // end function clearBuffer

        /**
          * Executes a sql-query against the connection.
          *  @access public
          *  @param string $sql                  The sql query
          * @see MysqlConnection::execute
          */
        
    function execute($sql) {
            
    $this->clearBuffer();
            return 
    $this->connection->execute($sql);
        }

        
    /**
          * Executes a sql-query against the connection and returns an iterator on the result set if any.
          *  @access public
          *  @param string $sql                  The sql query
          *  @return BufferedIterator            A buffered iterator for a result set.
          * @see MysqlConnection::select
          */
        
    function & select($sql) {
            
    $hash md5($sql);
            if (!isset(
    $this->queryBuffer[$hash])) {
                
    $result =& $this->connection->select($sql);
                if (
    is_a($result'MysqlIterator')) {
                    
    $this->queryBuffer[$hash] =& new ResultBuffer();
                    
    $this->queryBuffer[$hash]->load($result);
                }
            }
            return new 
    BufferedIterator($this->queryBuffer[$hash]);
        }
    }

    /**
      * Provides a container for a MysqlIterator
      */
    class ResultBuffer
    {
        var 
    $rows;

        function 
    ResultBuffer()
        {
            
    $this->rows = Array();
        }

        function 
    load(&$mysqlIterator)
        {
            while (!
    is_null($row $mysqlIterator->next())) {
                
    $this->rows[] = $row;
            }
        }

        function 
    get($index)
        {
            return 
    $this->rows[$index];
        }

        function 
    count()
        {
            return 
    count($this->rows);
        }
    }

    /**
      * BufferedIterator behaves exactly as MysqlIterator
      */
    class BufferedIterator
    {
        var 
    $resultBuffer;
        var 
    $_count;
        var 
    $_position;

        function 
    BufferedIterator(&$resultBuffer)
        {
            
    $this->resultBuffer =& $resultBuffer;
            
    $this->_position 0;
            
    $this->_count $this->resultBuffer->count();
        }

        
    /**
         *  Returns a hash of the next row.
         *  @return hash/null                   A hash corresponding to one result row or null on empty.
         *  @access public
         */
        
    function next() {
            if (
    $this->isEnd()) {
                return 
    null;
            }
            
    $row $this->resultBuffer->get($this->_position);
            ++
    $this->_position;
            return 
    $row;
        }

        
    /**
         *  Returns the total number of rows in the result set
         *  @return integer                     Total number of rows.
         *  @access public
         */
        
    function count() {
            return 
    $this->_count;
        }

        
    /**
         *  Just a dummy, in order to honor the MysqlIterator's interface
         *  @access public
         */
        
    function close() { ; }

        
    /**
         *  Accessor for end of input state.
         *  @return boolean                     True if file finished.
         *  @access public
         */
        
    function isEnd() {
            return 
    $this->_position >= $this->_count;
        }

    Sample
    PHP Code:
    require_once(dirname(__FILE__) . '/classes/change_class.php');
    require_once(
    dirname(__FILE__) . '/classes/QueryBuffer.php');

    $queryBuffer =& new QueryBuffer(new MysqlConnection('localhost''root''secret''changes'));
    $sql "SELECT * FROM insects";
    $result $queryBuffer->select($sql);

    while (
    $row $result->next()) {
        echo 
    "<p>";
        foreach (
    $row as $key => $value) {
            echo 
    "<b>$key:</b> $value<br>\n";
        }
        echo 
    "</p>\n";

    As you see, QueryBuffer is implemented as a decorator to Connection, rather than just extending Connection. This way it's the programmers choice to run through the buffer or directly against the connection.

  7. #32
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    VA, USA
    Posts
    57
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    If all it ever did was influence Propel then that would be a success.
    Well, the plan for Propel 2 is to move in this direction -- this more abstract, more of an object-storage solution which uses less database vocabulary.

    There have been some definite advantages to using a strict db-based system (based on Torque, of course) in building Propel, however. I would say that the learning curve is a lot gentler for people who understand databases. It's quite transparent: there's not a lot of magic happening but there's enough to make building db-driven OO apps a lot easier.

    But, in order to facilitate the above-and-beyond-SQL features like many-to-many relationships and possibly more complex inheritance models, the schema and templates will be redesigned for Propel 2. We'll also be using an IdentityMap to manage object graph consistency. Of course, unlike Hibernate, the plan is still to use a build framework to generate the php classes and SQL DDL. These RAD aspects of Propel seem to be quite popular.

    Cheers,
    Hans

  8. #33
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by kyberfabrikken
    What does this line actually do ?
    PHP Code:
    $this->execute('set transaction isolation level serializable'); 
    It is just the highest isolation level we could manage on the transactions in MySQL. Not quite full optimistic locks, but at least nothing can get to the database that wasn't understood at the time of the query.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  9. #34
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have been disassembling your code piece by piece, in order to try to improve on it. (And possibly adapting some of it to my own codebase). I'm a bit confused now though, about some of the methods in the Local class. Thoose in mention are :

    Local->_share()
    Local->_setOwner()
    Local->_getCollection()

    Obviously they are supposed to handle relations between objects, but would you mind elaborating a bit, since this is a rather confusing part of ORM ?

  10. #35
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by kyberfabrikken
    Obviously they are supposed to handle relations between objects, but would you mind elaborating a bit, since this is a rather confusing part of ORM ?
    This relates to what I said about it not being production quality. Writing code using TDD is sometimes a bit like a genetic algorithm. You end up with something that works pretty much by random steps. You need the pairing/review to inject back the human element. Even I don't fully understand it .

    Here is a rough guess (you have to look at the generated code too)...

    Local::_share() is for setting up joins. When reading an object with a many to one relation to another, the shared object is loaded as joined read only data into the others. That's OK for reading it back, but how do you set this arrangement up? That's where the _share() method comes in (it is chained from a more meningful method name in the generated code). Note that when you attach one object to another in this way, the shared object fields do not become available in the sharing object. This is one ofthose little glitches that hasn't been sorted out. Partly because it hasn't created any issues yet, althou it is untidy.

    local::_setOwner() is for when a new object is to be created as part of a colection of another. This is at the end of two generated method calls. You can follow it from the generated Car and CarPart classes...
    PHP Code:
    class CarPart extends Local {
        ...
        function 
    setCar(&$owner) {
            
    $this->_setOwner('Car'$owner);
        }
    }

    class 
    Car extends Local {
        ...
        function 
    addPart(&$item) {
            
    $item->setCar($this);
        }

    You call Car::addPart(). This calls back to the CarPart::setCar() on the collection item (the names are all defined in the XML schema file) which chains to the generic Local::_setOwner() method attaching the ID, as relational visibility goes from many to one (the opposite of object references of course).

    Local::_getCollection() is the generic code for pulling every member of the collection. as an iterator. All of the CarParts owned by a car for example. Again this will be chained from a nicely named method defined in the XML schema file, here Car::getParts().

    the terminology is: shared rows are many to one (read only) and collections are owned one to many.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  11. #36
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for that.

    _setOwner() and _getCollection() are quite intuitive. I guess that _share() is the one, that causes me the most headache.

    If I understand it right, _share is for setting up a one-to-many relationship. What confuses me probably is that you use the relational paradigm, rather than the object one. That is - The FamilyChild declares that it is related to the FamilyParent, rather than letting the FamilyParent declare that it has a collection of FamilyChild's.
    I would have expected that the impedance mismatch was handled on a deeper level. Looking at it now, I think that you're probably right in not doing that.
    Code:
        <persistent class="FamilyParent">
            <primary key="id"/>
            <field key="family_name"><string default="Bloggs"/></field>
            <field key="name"><string default="Fred"/></field>
        </persistent>
    
        <persistent class="FamilyChild">
            <primary key="id"/>
            <shared class="FamilyParent">
                <constant key="name" getter="getParentName"/>
                <constant key="family_name"/>
            </shared>
            <field key="name"><string default="Jimmy"/></field>
        </persistent>
    You don't deal with many-to-many relations in the examples, do you ? Obviously, there will have to be a middle-man, but this should be backed by some methods in the php-domain.
    How about one-to-one ? Useful for inheritance. (But that opens up for a hole lot of other problems, that is probably better not dealt at this point)

  12. #37
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Quote Originally Posted by kyberfabrikken
    You don't deal with many-to-many relations in the examples, do you ? Obviously, there will have to be a middle-man, but this should be backed by some methods in the php-domain.
    Indeed we don't. What I find in practice I find that if I cannot name the middle man, then something is probably not quite right with the data model anyway. Most of teh data model resource books never use many-to-many in their model catalogs and so I guess I just caught the habit. We would use a named middle man (va a join for one of them of course).

    Quote Originally Posted by kyberfabrikken
    How about one-to-one ? Useful for inheritance. (But that opens up for a hole lot of other problems, that is probably better not dealt at this point)
    One to one was the other relation that was implemented in a previous version of our persistence layer. We've never actually used it in any situation where it wasn't read only, hence we dropped the requirement. That's not to say that this requirement won't reappear.

    This library replaces the rather unwieldy PersistenceBroker version we had before. This new library is about half the size of the old one and client code is much cleaner. Not every feature of the old one made it into the new one though.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  13. #38
    SitePoint Enthusiast
    Join Date
    Jan 2005
    Location
    Sydney
    Posts
    43
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Marcus' work, along with his co-developers was great timing for me as I was looking around at the current solutions and didn't find one I liked. I am currently using it in my own project under PHP5. Using PDO, exceptions, etc, it makes a great way to map my objects to my database.

    Currently I haven't added anything major on top of it at the moment, but its easy use is all I need at the moment. I haven't come across anything troubling, maybe a minor mistake here or there, but that might've just been me when I was changing it to PHP5.

  14. #39
    SitePoint Member
    Join Date
    May 2005
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Changes not work for me

    i download changes and try to use but i need 2 files to execute simpletest example in .tar.gz file, i need unit_tester.php and reporter.php anybody have this files?

  15. #40
    SitePoint Addict been's Avatar
    Join Date
    May 2002
    Location
    Gent, Belgium
    Posts
    284
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    SimpleTest is a (very good) testing tool, it's not an example of the Changes library.
    Per
    Everything
    works on a PowerPoint slide

  16. #41
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Interestingly, the #1 http://www.google.com/search?q=unit_...p+reporter.php returns the exact right spot

  17. #42
    SitePoint Member
    Join Date
    May 2005
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    have anybody a liitle example (SQL table, xml file and php source?)
    i want to try changes but i have a document or a example to use.

  18. #43
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi.

    I am afraid it's a major mission as teh tarball was really just for writers of ORMs to play with. You need an XSLT transformer and you need to run it over an XML schema. the test sample is a minimal version, and you can compare teh XML with the test snippets to see what it is capable of.

    To actually run the tests and see if it's working, you will need Xalan (C++) as the XSLT engine, else you will have to modify the test.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  19. #44
    SitePoint Member
    Join Date
    Aug 2005
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hello, all!
    What ORM libs for PHP4 would you propose to use? I've tryed the PEAR:B_DataObject, but had lots of wiered thing while programming with it and finally it seems not to support Primary indexes of more then one field... Propel seems to be a solid decision, but its for PHP5 Please recomend me something, as I'm already tired to start it over with new lib every time...
    (I'm already colse to write something own...)

  20. #45
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There's a runtime enviroment for php4 in propel - It's only the build-part that requires php5.
    There's an incomplete list of various orm's at http://wiki.cc/php/Object_Relational_Mapping

  21. #46
    SitePoint Member
    Join Date
    Aug 2005
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanx,
    I've seen this list before, but the libs/tools are very poor (or not) described and not compared at all . So though this list let us know about existing solutions it does not help to choose... I'm a Java programmer and know that some times choosing a lib is half a work and sometimes the best idea is to write your own - so you will know each detail within.
    Thats why it would be perfect to add "user" (programmer that uses(ed) this lib) comment to this list.
    ...so you recomend to use Propel as the best solution to a PHP ORM? thanx!!! - off to investigate (one more time )

  22. #47
    SitePoint Member
    Join Date
    Dec 2005
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    After a while I hope you have an answer or I should try myself this aproach


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •