• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
DataMapper 1.6.0

#11
[eluser]stensi[/eluser]
I'm actually working on adding in extra functionality like that now. I'm still deciding on the best way to implement it in terms of ease of use and consistency but once I'm done, you'll be able to do all the various types of queries such as like, group by, order by, limit and offset.

Once I've completed and tested that ok, I'll post the new version, which already has many improvements on the validation side of things. I'm finding that part very useful for my sites right now. Cuts down the code in my controllers a huge amount.

Anyway, any suggestions/feature requests are welcome!

#12
[eluser]steelaz[/eluser]
Thanks, I'm using your DataMapper for a simple project (band->album->song type of thing). I like how it saves time and cuts down the code, but right now it's 50/50 between DataMapper and regular code, although I didn't switch to DataMapper validation yet.

Introducing features you mentioned would be a great improvement. Keep us posted.

#13
[eluser]stensi[/eluser]
At the moment, I've changed DataMapper's find() method to accept another two optional parameters, those being <b>limit</b> and <b>offset</b>. This is useful for paging your results. Example usages:

Code:
// Get all books from year 2000
$book = new Book(array('year' => 2000));

// Get all books from year 2000, limiting to 20 results
$book = new Book(array('year' => 2000), 20);

// Get all books from year 2000, limiting to 20 results,
// with an offset of 40 to view what would be the 3rd page of results
$book = new Book(array('year' => 2000), 20, 40);

Alternatively, I'm setting it up so you can do it this way:
Code:
$book = new Book();
$b->year = 2000;
$b->limit = 20;
$b->offset = 40;
$b->find();

Which gives the same result. You'll be able to setup a default limit in your DataMapper models, and offset will always default to 0 unless you specify it. After each find() call it will reset to 0 again.

<b>Note:</b>This newer version hasn't been uploaded yet as I'm hoping to finish off a few other additions first, including some cleaner handling of validation errors.

I'm having some problems coming up with a good naming convention for putting in the rest of the CodeIgniter DB functionality, such as ordering, grouping and like queries, into DataMapper. Obviously it's a little difficult to cram it all into the find() method and still keep it useable. Here's some samples of what I was thinking of doing:

Code:
// This will produce results ordered by the book name in ascending order, grouped by year.
$book = new Book();
$book->order = array('name', 'asc');
$book->group = array('year');
$book->find(array('year >' => 1990), 20);

I'm not too happy with having it so find() has a whole mess of optional parameters, such as:

Code:
$object->find($condition, $limit, $offset, $order, $group);

But if that's what you'd prefer instead of, or in addition to the example above it, I can do both or either.

It's likely that I'll end up having to add some other methods such as search() or find_like() for like queries but I'm hoping to get suggestions on the naming and usability.

Then there's select_max, select_min, select_avg etc that I was looking to add in. I've pretty much decided on those though. They'll look something like:

Code:
// Get the history genre
$genre = new Genre(array('name' => 'history'));

// Get the oldest year of this genres books
$oldest_year = $genre->book->min('year');

// Get the newest year of this genres books
$newest_year = $genre->book->max('year');

// Get the average year of this genres books
$average_year = $genre->book->avg('year');

// Get the total cost of buying all books from this genre
$total_cost = $genre->book->sum('price');

So yes, any suggestions on the naming/usage for ordering, grouping, and like queries and anything else are very welcome! :-)

<b>UPDATE</b>

The above is no longer valid as of version 1.2.

#14
[eluser]zeratool[/eluser]
Hey, stensi this is great library, may i suggest this:

$object->find((array $condition), (array $limit $offset), (array $order $group));

all condition parameters wrapped into array, also the limit and offset as well as the order and group.

thanks, keep this up. Smile

#15
[eluser]stensi[/eluser]
Thanks for the suggestion zeratool. I'll give that approach a try although I'm currently messing around with doing it the following way:

Code:
$u = new User();

// Get the first 10 moderators via method chaining
$u->where('role', 'moderator')->order_by('username', 'asc')->limit(10)->get();

// or do the same but without method chaining
$u->where('role', 'moderator');
$u->order_by('username', 'asc')
$u->limit(10)
$u->get();

// Show results
foreach($u->all as $user)
{
    echo $user->username . '<br />';

    // Just as an example, remove role from foo
    if ($user->username == 'foo')
    {
        $user->role = 'none';
        $user->save();
    }
}

It's a bit more like Active Record this way, since it uses its methods, so people already using Active Record will find the above much more familiar. It uses almost all of the existing methods available in Active Record except those few that are rendered obsolete by DataMapper (such as from() since DataMapper already knows the table name).

If I go with the above, it will mean the find() method is gone and replaced with get() or get_where() for the actual method that kicks off the data retrieval.

Anyway, this sort of approach, to me at least, looks to have more flexibility. All the rest of DataMapper remains the same since its handling of relationships, saving objects, validation and so on are the main parts that make it a DataMapper.

Would you prefer I continue with this approach?

<b>UPDATE:</b>
Actually, I think I will do it this way. I've finished off implementing it and it's actually made some of the other functions tidier and work a little better, such as validate and save.

I'll do some more testing to make sure it's good to release and then I'll update the documentation to reflect the new version.

#16
[eluser]stensi[/eluser]
Version 1.2 has been released!

View the Change Log to see what's changed.

In short, the find method has been removed and replaced with the get method, using functionality similar to retrieving data with CodeIgniter's Active Record class. My post above shows one of the many ways in which you can now populate your objects (including method chaining). Validation has been improved too, most specifically the error messages. Automated timestamping is also included.

Enjoy :-)

#17
[eluser]BaRzO[/eluser]
thanks for your work i am following your posts and i am reading your user guide
thanks for all Wink

#18
[eluser]Boyz26[/eluser]
Great job!!

I like your very friendly user guide especially.

Question: Will there be a big difference if I use many-to-many for one-to-many or even one-to one relationships?

Thanks!

#19
[eluser]stensi[/eluser]
Glad you like it :-)

Yep, there is quite an important difference actually. If you use Many to Many for what should be a One to Many or One to One relationship, then DataMapper will not be able to ensure the integrity of your relationships.

<u>For example:</u>
Let's say you have a <b>users</b> table and a <b>groups</b> table and you have a business requirement that each user can belong to ONLY ONE group but a group can have many users. So, this means the users table will have a One to Many relationship with the groups table.

To set this relationship in your DataMapper models, the User DataMapper model would have:

Code:
$has_one = ("group" => "groups");

And the Group DataMapper model would have:

Code:
$has_many = ("user" => "users");


DataMapper has a series of integrity checks when a relationship is added/updated/deleted between tables with One to One and One to Many relationships.

When saving a relationship between a user and a group (One to Many) DataMapper will check to see if the user already has an existing relationship with a group, and if it does, it will update that relationship record rather than adding a new relationship record. If the user has no relationship record, one is added. This ensures there is only one relationship record for each user, between the users and groups tables.

If you had set it up to be a Many to Many, this would mean a user can belong to many groups (and a group can have many users). So, if user FOO was related to group A and you then saved a relationship between user FOO and group B, user FOO would be related to both group A and group B.

Now, since user FOO belongs to more than one group we've broken our initial business requirement that each user can belong to only one group. Setting it up as One to Many would have ensured the business requirement was adhered to.

A situation where you would use a Many to Many relationship would be something like <b>skills</b> and <b>employees</b>. Each employee can have multiple skills (you'd hope), and a skill can be listed against multiple employees, thus a Many to Many relationship.

I hope that example makes it clearer for you.

You can read a longer explanation of the relationship types in the DataMapper User Guide.

#20
[eluser]Boyz26[/eluser]
That's great!! Thanks for your wonderful reply. Now I value your DataMapper more!


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2021 MyBB Group.