Page 1 of 3

Resultset total count - simple question

Posted: Tue Sep 14, 2010 8:39 am
by alex.barylski
As the title suggest, this is a simple question: When you implement a model method that queries a large dataset and returns paginated results, how do you return the number of total records, in order to calculate things like, the total number of pages, etc?

Do you:

1. Implement each model to have a getTotalCount() method to complement selectAllRecords() type methods
2. Do you have your selectAllRecords() return an array, with the first element being the count and the second being the records
3. Do you return a resultset object which has mehtods, such as getResults() and/or getCount()

Each has it's pros and cons, I've tried all three in my current setup, each with caveats, so I am just curious, which do you prefer?

Cheers,
Alex

Re: Resultset total count - simple question

Posted: Tue Sep 14, 2010 8:54 am
by Weirdan
Another option: return object implementing Countable and Traversable. Then use it like this:

Code: Select all

Page <?=e($_GET['page'])?> of <?=ceil(count($result) / min(intval($_GET['perpage']), 1))?>
<ul>
<? foreach ($result as $row) : ?>
    <li><?=e($row['item'])?></li>
<? endforeach; ?>
</ul>

Re: Resultset total count - simple question

Posted: Tue Sep 14, 2010 11:01 am
by alex.barylski
I would personally put that in the same category as a resultset object, although I'm not sure what the Countable would do? I am not interested in counting the number of records to render, but rather the number of total records outside of the paginated result.

The problem I have with returning a resultset object (which is so nice as it allowed me to abstract querying the database inside the model, but return an associative array, or in the rare case a buffered query if the resultset was massive huge), is that now the controller layer is slightly coupled with the DAL, and abstracting the resultset object in the model layer, didn't make sense for me.

Because the resultset object is part of the DAL/DB abstraction layer, if the model were to ever use a third party service, like a CSV file or web service, the resultset object wouldn't be available adn thus force me to refactor the code if I were to ever switch.

Duplicating the resultset object in the model layer just felt, convoluted?!?

All of this is highly subjective and heavily dependent on how you architect your applications, where you need flex points, the amount of abstraction you prefer, etc. I am just curious o hear others views as to how they address the issue.

Cheers,
Alex

Re: Resultset total count - simple question

Posted: Tue Sep 14, 2010 2:21 pm
by VladSun
The 3th one

Re: Resultset total count - simple question

Posted: Tue Sep 14, 2010 3:33 pm
by alex.barylski
It's the one I prefer as well, but cannot get over the added coupling between the DAL and controller. :)

Re: Resultset total count - simple question

Posted: Wed Sep 15, 2010 1:34 am
by VladSun
I use a Decorator pattern to change the Model query (i.e. to append LIMIT OFFSET) and add an additional query to retrieve the total number of records.

Code: Select all

class User extends Collection_Controller
{
	function __construct()
	{
		parent::__construct();

		$this->setModel(new Pagination(new User_Collection_Model()));
	}
}
Also, I don't pass the Model itself to the View - I use a Response object to collect result data, error/warning messages, etc.
The Response object is passed to the View. Maybe it's not a good practice but it works for me :)

Re: Resultset total count - simple question

Posted: Wed Sep 15, 2010 9:35 am
by alex.barylski
Also, I don't pass the Model itself to the View - I use a Response object to collect result data, error/warning messages, etc.
The Response object is passed to the View. Maybe it's not a good practice but it works for me
Seems a little backwards to me, but that doesn't make it wrong I don't think, just different. Personally the response is the last component in the execution pipeline, so the view is rendered and the result assigned to a response->setContent() at which point the framework takes care of sending to stdout.

My only concern with the response being passed to the view, is the coupling of layers (which may or may not be a concern). If the views have a dependency on a response object, could you reuse that view in an environment without a response object?

For example, a cronjob, might use a view to load a template to render an HTML email, in this case the response object, is not an HTTP response, but rather a mailing object, such as SwiftMailer. For that reason, I would personally keep the two decoupled and simply pass the results of the rendered view to whatever object I desire, whether that be a HTTP response object, SMTP object or possibly a File if you were caching, etc.

Of course, this is with a severely limited understanding of your architecture, etc.

Cheers,
Alex

Re: Resultset total count - simple question

Posted: Wed Sep 15, 2010 12:11 pm
by VladSun
My Response object is a composite object containing Error object, Warning pbject, Result object, etc.

It's not HTML or something like that.

My "views" by default are simple json_encode(Response) - just ExtJS AJAX formated messages :)

So there is no coupling with the Model I think. The response object is just a layer between the Model and the View.

Re: Resultset total count - simple question

Posted: Wed Sep 15, 2010 1:01 pm
by josh
I have a special model for this, the "finder". So if I have a Widget model, I should have a Widget_Finder

->findAll(1,100) // would give rows 1-100
->findAll() // loads all the rows
->findOne(1) // finds row with primary key = 1
etc...

These methods generally follow the data mapper pattern.
PCSpectra wrote: Personally the response is the last component in the execution pipeline,
For a given sub system, yes. Lots of components have Request/Response objects. Never heard of it for pushing data to the view, but hey.. whatever works. Would be better to term it as a "result" and not a "response" for the reasons you point out. Although a soap server, for example, has a response, you're probably right that it implies an actual response, as opposed to just a "result".

Re: Resultset total count - simple question

Posted: Wed Sep 15, 2010 2:21 pm
by alex.barylski
truth be told, my framework implements a very basic response object and later inherits from it with an HTTP reponse object, which essentially wraps the HTTP response. It adds methods for things such as redirection, which wouldn't be required when sending emails via cronjob. That being said, I use the same framework VladSun does and everything must be output in JSON format, and the view/rendering is effectively handled client-side. The response object passed to the front controller by the framework is still the generic HTTP one, although one more layer of abstraciton could be added so as to eliminate having to constantly set custom headers in every action.

I supposed one way around introducing yet another reponse object simply for the purpose of eliminating setting headers other than "text/html" would be to have a view object set the reponse for you, and in the process convert a native PHP array into a JSON array. The view in this case is really simple and so the coupling of response and view isn't all that serious, as I would normally consider it anyways. :)

Cheers,
Alex

Re: Resultset total count - simple question

Posted: Wed Sep 15, 2010 2:38 pm
by VladSun
My Controller hierarchy starts (excluding the base Controller class itself) with a ViewContext_Controller class, which depending on the URL requested (i.e. http://example.com/user/get.html or http://example.com/user/get.json) loads a different View (if it's defined) for it. All Views know about the Response object API and can handle it.

PS: I think that the View is always coupled to the Model - it's a pure example of the Observer pattern. Adding an intermediate layer (the Response object) may introduce some decoupling, but it's still not enough.

Re: Resultset total count - simple question

Posted: Wed Sep 15, 2010 2:41 pm
by VladSun
josh wrote:Would be better to term it as a "result" and not a "response" for the reasons you point out.
I have to agree :)

Re: Resultset total count - simple question

Posted: Wed Sep 15, 2010 2:43 pm
by VladSun
VladSun wrote:So there is no coupling with the Model I think. The response object is just a layer between the Model and
the View.
VladSun wrote:I think that the View is always coupled to the Model - it's a pure example of the Observer pattern. Adding
an intermediate layer (the Response object) may introduce some decoupling, but it's still not enough.
Blah .... :drunk:

Re: Resultset total count - simple question

Posted: Thu Sep 16, 2010 12:07 pm
by alex.barylski
Hahaha :drunk: indeed :p

Cheers,
Alex

Re: Resultset total count - simple question

Posted: Thu Sep 16, 2010 1:03 pm
by josh
Yeah almost any literature I've read about MVC, the view observes the model. That way when the model decides to update itself (maybe in a multi-threaded environment, some other process has a reference to our model and updates it) - the view should update too. This is unnecessary in web but I still think the dependencies should be the same.

What framework do you guys use? Also just a friendly request, please try to post less "fluff". ("I agree"), on some forums they have rules against that. It makes the thread impossible to read when you quote a paragraph of text just to add, "indeed", and nothing more.