ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

DataMapper 1.6.0

September 05, 2008 12:32pm

Subscribe [115]
  • #856 / May 19, 2009 12:18pm

    OverZealous

    1030 posts

    What ever you do, don’t EVER use the code above!

    Otherwise I could fabricate an HTTP POST that changes the id before a save, or something else, and edit the data on an item I might not have access to.

    Always validate your $_POST input.  If nothing else, do something like this:

    $foreach($_POST as $k => $v) {
        if(in_array(array('name', 'value1', 'value2'), $k)) { // may be backwards
            $u->{$k} = $v;
        }
    }
  • #857 / May 19, 2009 12:22pm

    Matthew Lanham

    145 posts

    Well yes, sorry i didn’t think my post through, it was a short example of how we actually do it, which involves some encryption and session based checks before any data is stored.

  • #858 / May 20, 2009 12:38am

    oddman

    89 posts

    Hi stensi,

    I think datamapper is one of the best ORMs available for CI atm, and I’d like to be able to contribute to the project, as I believe there’s a lot I could add (and forking it, I do not believe is beneficial for anyone 😛). If not, that’s fine - I can just do it for myself 😛

  • #859 / May 20, 2009 4:28pm

    IamPrototype

    135 posts

    I don’t get it. What’s so good about datamappers? What’s its pros (...and cons)?

  • #860 / May 20, 2009 11:36pm

    OverZealous

    1030 posts

    @IamPrototype
    First, I recommend reading stensi’s original introduction.  Look through the code examples, and you can see how an ORM can eliminate hard-coded SQL (a big mistake in any manageable application), and make your code easier to read.

    It also automatically handles relationships between objects, including automatically deleting complex relationships.  Some (maybe even much) of what DM can do can be duplicated with RDBMS configuration, but then you are splitting your application configuration between multiple sources.

    Finally, DataMapper really increases the speed of development, by allowing you to look at your data as a series of inter-related objects, instead of unrelated tabular data.

    If you are uncomfortable with OOP development, it may seem strange at first.  After awhile, however, you will see how DM makes your code much easier to read, and it really helps when separating your application into a proper Model-View-Controller architecture.

    Beyond that, read through this forum (and my extended DMZ forum) for examples and information.

    (FYI: The only reason my version of DataMapper exists is that stensi has not been around since February [last I checked], and I have been trying to provide support, enhancements, and bugfixes.  DMZ is fully backwards compatible with DataMapper.)

  • #861 / May 21, 2009 5:30am

    IamPrototype

    135 posts

    EDIT: I think I understand how it works now and how great it actually can be although I’d like to know if I have to relate and delete relation whenever I don’t need it anymore. I assume when I delete a relation DataMapper will delete something in my database, or am I completely wrong? Maybe I’m too confused and I’ll just have to use delete when I want to delete a user and his relation from the database (like “real” deleting, lets say he was a bad user, LOL).

    Correct me if I’m wrong! I’m just so damn curious learning new stuff!

  • #862 / May 21, 2009 5:32am

    IamPrototype

    135 posts

    EDIT #1: I’ve deleled my example since it was wrong… not completely… but just wrong in some ways. What I’d also like to know is the fields in my validation HAS TO BE THE SAME that the fields IN MY TABLE is named otherwise DataMapper won’t “understand what I’m trying to do”, right?

    EDIT #2: Now that this library is out and makes it a lot more easy with coding etc. There isn’t really a point of using an auth library now? I mean, everything is going on in models (the login method, register method) and controllers.. before DataMapper the login method, register method etc. was in the auth library. So what’s the point of creating other libraries now?

  • #863 / May 21, 2009 7:15pm

    tdktank59

    322 posts

    Alright Ive finally hit another wall…

    So here is what I have.

    $sql = "SELECT  `problems`.*,
                            `members`.`name` as `member_name`,
                            `problem_statuses`.`name` as `status_name`,
                            `owners`.`first_name` as `owner_first_name`,
                            `owners`.`last_name` as `owner_last_name`,
                            `assigned_to`.`first_name` as `assigned_to_first_name`,
                            `assigned_to`.`last_name` as `assigned_to_last_name`
                    FROM `problems` as problems
                    LEFT JOIN `members` as members
                        ON `members`.`id` = `problems`.`member_id`
                    LEFT JOIN `problem_statuses` as problem_statuses
                        ON `problem_statuses`.`id` = `problems`.`status_id`
                    LEFT JOIN `users` as owners
                        ON `owners`.`id` = `problems`.`owner_id`
                    LEFT JOIN `users` as assigned_to
                        ON `assigned_to`.`id` = `problems`.`assigned_to_id`
                    WHERE (`members`.`name` LIKE '%".$sSearch."%' 
                          OR `members`.`sid` LIKE '%".$sSearch."%' 
                          OR `problem_statuses`.`name` LIKE '%".$sSearch."%')
                        AND `problems`.`id` IN (".implode(',',$problem_id).")
                    LIMIT 0,10";
    
    $result = mysql_query($sql);
            echo mysql_error();
            while ($m = mysql_fetch_assoc($result))
            {
                echo $m['sid'].' - 
    '.$m['name'].' - '.$m['status_name'].' - 
    '.$m['owner_first_name'].' '.$m['owner_last_name'].' - 
    '.$m['assigned_to_first_name'].' '.$m['assigned_to_last_name'].'
    ';
            }

    Note: I did not escape the sql. because at this point it is not in a live environment.
    And I was hoping to get this working with datamapper which would end up clearing it.

    I’m having issues turning that into data mapper… Of course the selects wouldn’t matter with data mapper but This is a working example of the code… All the values above are the values I need to pull out of the system.

  • #864 / May 24, 2009 10:15pm

    OverZealous

    1030 posts

    @IamPrototype
    I’m glad you have it figured out.  I have been gone for about a week, so I wasn’t able to respond.

    If you want to delete an object, you always use $object->delete().  This will also delete every relationship (ie: from the join tables) for $object.

    If you just want to delete a relationship, you use $object->delete($other_object).  This will not delete any objects.

    If you find yourself deleting the same objects and related objects (in different controllers) frequently, you might want to add a dedicated method to your object. (I call mine delete_deep.)

    DM may or may not replace your Auth code.  I ended up integrating one that heavily modifies CodeIgniter’s Session library with the example code from stensi.  Other libraries will likely be the same (in that you’ll have to modify the other library to make it work).

  • #865 / May 24, 2009 10:31pm

    OverZealous

    1030 posts

    @tdktank59

    The problem you are having is one I have complained about: CodeIgniter’s ActiveRecord (which DM heavily relies on) does not support query grouping (a.k.a., parentheses).  Therefore, you basically cannot have a complex query where parts of it are grouped, and other parts are not, using just AR or DM methods.

    That being said, there is a hackish solution that works well.  Try this (I have had to “fix” CodeIgniter’s DB class, so this might not work):

    $problem = new Problem();
    
    $problem->join_related('member', array('name'));
    $problem->join_related('status', array('name')); // guessing here
    $problem->join_related('owner', array('first_name', 'last_name'));
    $problem->join_related('assigned_to', array('first_name', 'last_name'));
    // create special query section
    $search = '';
    $sSearch = $problem->db->escape_str($sSearch);
    foreach(array('members.name', 'members.sid', 'status.name') as $col) {
        if(!empty($search)) { $search .= ' OR '; }
        $search .= "{$col} LIKE '%{$sSearch}%'";
    }
    // note: calling directly on the db library, to bypass DataMapper.
    $problem->db->where('(' . $search . ')');
    $problem->where_in_related_problems($problem_id);
    $problem->get();
    
    // verify the query
    echo '<pre>' . $problem->db->last_query() . '</pre><p>‘;
    </pre>

  • #866 / May 24, 2009 11:19pm

    Nabeel

    15 posts

    Sorry for not reading through the entire thread; but looking through the docs, I don’t see this, but is it possible to change which columns are used for the joins/FK? I think it assumes tablename_id to be the FK?

    Also, I’ve always used pure SQL code, but I’m interested in this obviously for ease of use. What’s the CPU and more importantly for me, the memory ramifications for this level of abstraction?

  • #867 / May 24, 2009 11:44pm

    OverZealous

    1030 posts

    No, you cannot change the column names.  The closest you can get is to use DMZ and use custom relationships, but that is a lot of work for that, and they still must be in the form <relatedfield>_id, so there isn’t much improvement.  Also, it isn’t <tablename>_id, it’s <model>_id.  This is important, because the table is named, for example, users (plural), but the model is user (singular).

    stensi and others have done research in the past on speed/ram usage.  The speed ramifications will depend highly on the type of queries you are writing, and how you are looking into the data.  For high-volume websites with multiple, complex queries, DM might not work the best.

    For example, a large query set will probably not be affected too seriously by speed, although RAM usage can get high.  This is because most of the work would be done by the DB server, but each row of the result has to be turned into a PHP Object.

    However, many very small queries might be less efficient.  The only way to know for sure is to test it yourself, on your dataset, with your queries.

    If you are worried about speed, definitely look into DMZ, because I have included methods to allow you to join the results from multiple tables into one object.  This can help by pushing much of the work onto the DB server.  See join_related() on the first post for more information.  DMZ also allows for in-table foreign keys (for $has_one relationships), which can also speed up queries by reducing the number of joins.

  • #868 / May 24, 2009 11:57pm

    Nabeel

    15 posts

    Interesting. I’m using IgnitedRecord at the moment, haven’t had a problem really, but I’ve still had to write alot of the join-heavy queries by hand, which I prefer. Nearly every query I do has at least one join. I think most of my time has been understanding on how to relate each table to each other in terms of object relationships.

    Though now, I am changing column names to <fk>_id versus <fk>id, which seems to be mainly what I want. It’s a little tough to benchmark too between different libraries, I think I’ve spent more time on messing with ORM than doing actual work :D

    I’m probably just being over-obsessive about memory usage and all that anyway.

  • #869 / May 25, 2009 12:14am

    Nabeel

    15 posts

    Also, the requirement for joining tables, it’s not always needed. I guess a bit of a restriction there.

  • #870 / May 25, 2009 12:21am

    OverZealous

    1030 posts

    I’m probably just being over-obsessive about memory usage and all that anyway.

    I think this is an easy mistake to make, that most devs make when switching to an ORM.  My general rule is, get the code working (cleanly) first, then worry about optimizing.  You don’t want to spend a lot of time to optimize something, and then change (or delete) the method later!

    I think I’ve spent more time on messing with ORM than doing actual work :D

    Aaaaand that’s how I ended up posting nearly 300 times supporting DataMapper, and writing several important enhancements to the core… 😊

    One thing I like about DataMapper (and DMZ) is that it generates very clean queries, because it is written on top of ActiveRecord.  If at all possible, try to avoid hand writing any SQL code.  If you do, you’ll end up with a mess to manage later on, especially if you make any model name changes.

    Also, the requirement for joining tables, it’s not always needed. I guess a bit of a restriction there.

    (I think) This is what I was referring to above, about DMZ and supporting in-table foreign keys.  DataMapper requires a dedicated table for every join, even $has_one joins.  DMZ supports having a field called <relatedfield>_id on a model’s table.  This can lead to significant table reduction (in my case, I removed over 20 tables).

    DMZ is a drop-in replacement for DataMapper, fully backward compatible.  The only reason I “forked” it is because stensi has (temporarily, hopefully) stopped updating DataMapper, and there were features that needed to be written.  The extra features, sadly, are not nearly as well documented.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases