CodeIgniter Forums
DataMapper 1.6.0 - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=22)
+--- Thread: DataMapper 1.6.0 (/showthread.php?tid=11358)



DataMapper 1.6.0 - El Forum - 05-21-2009

[eluser]IamPrototype[/eluser]
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!


DataMapper 1.6.0 - El Forum - 05-21-2009

[eluser]IamPrototype[/eluser]
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?


DataMapper 1.6.0 - El Forum - 05-21-2009

[eluser]tdktank59[/eluser]
Alright Ive finally hit another wall...

So here is what I have.

Code:
$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'].'<br />';
        }

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.


DataMapper 1.6.0 - El Forum - 05-24-2009

[eluser]OverZealous[/eluser]
@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).


DataMapper 1.6.0 - El Forum - 05-24-2009

[eluser]OverZealous[/eluser]
@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):

Code:
$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>';



DataMapper 1.6.0 - El Forum - 05-24-2009

[eluser]Nabeel[/eluser]
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?


DataMapper 1.6.0 - El Forum - 05-24-2009

[eluser]OverZealous[/eluser]
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.


DataMapper 1.6.0 - El Forum - 05-24-2009

[eluser]Nabeel[/eluser]
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 Big Grin

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


DataMapper 1.6.0 - El Forum - 05-24-2009

[eluser]Nabeel[/eluser]
Also, the requirement for joining tables, it's not always needed. I guess a bit of a restriction there.


DataMapper 1.6.0 - El Forum - 05-24-2009

[eluser]OverZealous[/eluser]
[quote author="Nabeel" date="1243238275"]I'm probably just being over-obsessive about memory usage and all that anyway.[/quote]

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!

Quote:I think I've spent more time on messing with ORM than doing actual work Big Grin

Aaaaand that's how I ended up posting nearly 300 times supporting DataMapper, and writing several important enhancements to the core... Smile

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.

Quote: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.