Welcome Guest, Not a member yet? Register   Sign In
RapidDataMapper, a new Object-Relational-Mapper
#31

[eluser]hung5s[/eluser]
I like the idea but does the work to create mappers is heavy ?
#32

[eluser]m4rw3r[/eluser]
Yes, the mapper creation is very time consuming, especially compared to the time spent using the generated mapper. But as the mappers are cached during production, the app only needs to render them once, when the app is deployed.
This gives a huge performance increase, as only the connection, query builders, mappers and data objects needs to be loaded. So instead of loading 50! files, it only loads about 7 + 1 for each mapper.

To activate the mapper cache, set $cache_mappers to true (the variable is located in app/config/database.php).
To refresh the mapper cache, just delete all the files which are located in app/mappercache and RapidDataMapper will refresh them automatically.
#33

[eluser]m4rw3r[/eluser]
I've made a very simple performance comparison between Doctrine and RDM:

Result: RDM is about equal in performance when it comes to extracting a whole object graph or multiple objects, but it is very fast when fetching a single row.

Objects:
Code:
Country:
  id
  name

Region:
  id
  name
  country_id

City
  id
  name
  country_id
  region_id

Tests

Object Graph:

Fetch the country Sweden, all its regions and their corresponding cities (which means 239 rows with all joined through LEFT JOINs).
10 repetitions, to get it below 30 seconds all times (goes for both RDM and Doctrine).

Single object:

Fetching a single row from the country table with the id 23 (and no caching was allowed).
1000 repetitions.

Multiple objects:

Fetching all related regions to the country with the id 23.
1000 repetitions.

Results
In seconds

RDM:

Object Graph: 16.068867921829
Single Object: 1.3140540122986
Multiple Objects: 2.9177198410034

Doctrine:

Object Graph: 16.564059019089
Single Object: 17.68523812294
Multiple Objects: 2.5408611297607

CI's AR:

Object Graph: 0.16973185539246 (Not really comparable, because it fetches a single row for each country-region-city combination)
Single Object: 2.1052830219269
Multiple Objects: 2.3604340553284

(Have no idea what happened in the Single Object fetch for Doctrine, I just used Doctrine_Core->getTable('Country')->find(23)Wink

NOTE: No caching has been used, not by RDM nor by Doctrine (unless doctrine does some caching without the user's knowledge).

PS. I have not done any specific performance optimizations for RDM during any of the stages in development, so this speed is currently inherent to its design Wink
But I think I will do some soon, fetching large object graphs was hard work and I had to go down to below 10 iterations to get it under 30 all times (for both Doctrine and RDM).
#34

[eluser]Jelmer[/eluser]
@m4rw3r: performance looks great!

And I got another question Wink

Maybe you've already answered this somewhere in the manual but I couldn't find it right now: I was wondering if RDM has protection against SQL injection or if I have to check the input before giving it to RDM?
(Not really important for the application I tested/am using it in, but if I consider using it in any other projects that'll play a part in my decision)
#35

[eluser]m4rw3r[/eluser]
Yes, it has protection against SQL injection. But as always, be sure that you don't let user input go unfiltered/unrestricted to important stuff. Smile

About the tests, I did not try the "boot test"; that is, testing how fast the database abstraction and ORM loads. This test is really important for seeing how responsive requests will be.
#36

[eluser]Jelmer[/eluser]
I actually decided to replace my own ORM implementation with RDM in one of my 2 projects and ran into a bug in the MY_Session.php CI compatibility. I didn't notice it before because my other application didn't use the DB for sessions (by accident, I turned it on now).

On line 93 it says:
Code:
$query = $this->CI->db->select();

Which should be:
Code:
$q = $this->CI->db->select();
#37

[eluser]m4rw3r[/eluser]
Thanks, it is now fixed in the dev version.
#38

[eluser]Jelmer[/eluser]
Maybe again something I should have read in the manual, but I couldn't find out how to get a MAX(`column`)/MIN(`column`) done so I added 2 carbon-copies of the count() method in the DB_Query_Select class:
Code:
public function min($column)
{
    if($this->escape)
    {
        // escape the string
        $column = $this->_instance->protectIdentifiers($column);
    }
    
    // save it, so we still can use this query object here
    $tmp = $this->columns;
    
    // construct the MIN
    $this->columns = array('MIN(' . $column . ')');
    
    // call
    $ret = $this->_instance->query($this->__toString());
    
    // reset the columns
    $this->columns = $tmp;
    
    // return unless error
    if($ret === false)
    {
        return false;
    }
    else
    {
        return ($r = $ret->val()) !== false ? $r : false;
    }
}

public function max($column)
{
    if($this->escape)
    {
        // escape the string
        $column = $this->_instance->protectIdentifiers($column);
    }
    
    // save it, so we still can use this query object here
    $tmp = $this->columns;
    
    // construct the MAX
    $this->columns = array('MAX(' . $column . ')');
    
    // call
    $ret = $this->_instance->query($this->__toString());
    
    // reset the columns
    $this->columns = $tmp;
    
    // return unless error
    if($ret === false)
    {
        return false;
    }
    else
    {
        return ($r = $ret->val()) !== false ? $r : false;
    }
}
Good or bad solution?

(EDIT after suggestion of sophistry)
#39

[eluser]sophistry[/eluser]
you probably don't want to (Int) the output of MIN or MAX
#40

[eluser]Jelmer[/eluser]
Good point, though for my current use it doesn't make any difference.
(I edited my previous post)




Theme © iAndrew 2016 - Forum software by © MyBB