Marijn Haverbeke wrote:
Unfortunately I don't quite understand what you are trying to do, but it seems that in the simple case something like this (untested) might work...
Sorry, I forgot that using the word paging without the context can be confusing. By paging, I meant paging in the web pages - if I have 100 results to a query, I would like to show that to the user in chunks of 20 rows over 5 pages, to avoid huge requests and make the user's life easier.
To avoid putting this 100-row result in the session and then paging over it (can be quite inefficient if there are lots of results), I want to retrieve the count of results, and then retrieve small piece of them according to page numbers with :offset and :limit.
So something like this:
(query (:select 'id 'name :from 'cities))
Would turn into:
(query-dao 'city (:limit (:offset (:order-by (:select 'id 'name :from 'cities) 'name) offset) limit))
But to calculate how many pages I have to create links to, I need to have the number of results before the query actually runs. So, number of results divided by limit should give me the number of pages this result set would run into.
But to avoid writing a similar query twice, I'm trying to change the first query into this (the aim is to write a macro which does this automatically), to get the number of rows:
(query (:select :raw("count(*)") :from 'cities) :single)
Also, the element :count was not added to postmodern - I have checked the source too. So, I have to use :raw for now - please correct me if I'm wrong.
(defun query-subst (query) (let ((from (position :from query))) `(:select (:count '*) ,@(nthcdr from query)))
Perhaps you can already see that this does not help - position cannot look into trees (works only with sequences) and the select statement can be arbitrarily long. I think my problem can be simply put this way: I need to replace everything between :select and :from with a single (:count *) or (:raw "count(*)").
Perhaps I'm being finicky - I'm just looking to cut some extra lines of code and move the entire paging-related code into one macro.
Thanks much, Vamsee.
Hi,
By paging, I meant paging in the web pages - if I have 100 results to a query, I would like to show that to the user in chunks of 20 rows over 5 pages
Ah, I see what you mean now. And I suppose it would be possible to write some kind of macro for that. Or make the query a real run-time list, and use compile-query to execute it. I don't have a lisp or very much time right now, so I won't help you write the functions, but you can bug the people in #lisp on irc about it or something if you can't figure it out.
Also, the element :count was not added to postmodern - I have checked the source too. So, I have to use :raw for now - please correct me if I'm wrong.
Did you try (sql (:count '*))? It works. By magic.
Actually, S-SQL has a fallback rule for operators it does not know. They are rendered as simple function calls -- function(arg1, arg2, ...) -- so things like :count and any stored procedures you might define work without the need for defining the operators.
Regards, Marijn
postmodern-devel@common-lisp.net