From info at jensteich.de Thu Aug 9 18:57:36 2007 From: info at jensteich.de (Jens Teich) Date: Thu, 9 Aug 2007 20:57:36 +0200 Subject: [postmodern-devel] Join Slots Message-ID: <011c01c7dab7$2a80e870$6b02a8c0@JensSony> I'm considering to change from clsql to postmodern because I need unicode support. In clsql the following viewclass definition is possible with join slots: (clsql:def-view-class elements () ((guid :reader element-guid :db-kind :key :type (string 36)) (lang_id :db-kind :key :type (string 2)) ... more ... 'normal' slots) (produkt :reader product-element :db-kind :join :db-info (:join-class produkte :home-key (guid_objekt lang_id) :foreign-key (guid lang_id) :set nil))) (:base-table project-elements)) so that I can access the joined records easily via (product-element instance-of-element) How do I do this with postmodern? Thanks Jens From info at jensteich.de Fri Aug 10 21:26:13 2007 From: info at jensteich.de (Jens Teich) Date: Fri, 10 Aug 2007 23:26:13 +0200 Subject: [postmodern-devel] conditional query building Message-ID: <007001c7db95$179a0b90$6b02a8c0@JensSony> > (postmodern:sql (:= 's 'tr)) => "(s = tr)" > (postmodern:sql (if t (:= 's 'tr))) => Error: Undefined operator := in form (:= (QUOTE S) (QUOTE TR)). How do I make this work? I want to build more complex where clauses using cl:if. Jens From info at jensteich.de Sat Aug 11 15:41:42 2007 From: info at jensteich.de (Jens Teich) Date: Sat, 11 Aug 2007 17:41:42 +0200 Subject: [postmodern-devel] query with keyword :on Message-ID: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> This is an example from the documentation which gives strange results on Lispworks 5.0.2. I'm using the latest version of postmodern (1.02) CL-USER 3 > (postmodern:sql (:select (:+ 'field-1 100) 'field-5 :from (:as 'my-table 'x) :left-join 'your-table :on (:= 'x.field-2 'your-table.field-1) :where (:not-null 'a.field-3))) "(SELECT (field_1 + 100), field_5 FROM my_table AS x LEFT JOIN your_table ON (x.field_2 = your_table.field_1), your_table, on, (x.field_2 = ................................^ your_table.field_1) WHERE not_null(a.field_3))" Jens PS my previous problem with if statement is solved, I needed a macro instead of a function From marijnh at gmail.com Mon Aug 13 08:19:39 2007 From: marijnh at gmail.com (Marijn Haverbeke) Date: Mon, 13 Aug 2007 10:19:39 +0200 Subject: [postmodern-devel] conditional query building In-Reply-To: <007001c7db95$179a0b90$6b02a8c0@JensSony> References: <007001c7db95$179a0b90$6b02a8c0@JensSony> Message-ID: Hello Jens, I'm not entirely sure what you want to do here. Do you want the IF to appear in the query, or the query to be adjusted depending on the outcome of the IF? In the second case, look into SQL-COMPILE, which allows the query s-expression to be built at run-time (rather than compile time, as with the SQL macro). Cheers, Marijn From marijnh at gmail.com Mon Aug 13 08:21:39 2007 From: marijnh at gmail.com (Marijn Haverbeke) Date: Mon, 13 Aug 2007 10:21:39 +0200 Subject: [postmodern-devel] query with keyword :on In-Reply-To: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> References: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> Message-ID: Hello, Are you sure the problem is not just the fact that the tables do not exist? You didn't post an actual error message, so I'm not sure what happens. Cheers, Marijn From marijnh at gmail.com Mon Aug 13 08:30:41 2007 From: marijnh at gmail.com (Marijn Haverbeke) Date: Mon, 13 Aug 2007 10:30:41 +0200 Subject: [postmodern-devel] Join Slots In-Reply-To: <011c01c7dab7$2a80e870$6b02a8c0@JensSony> References: <011c01c7dab7$2a80e870$6b02a8c0@JensSony> Message-ID: Hello Jens, Postmodern does not really do anything like join-slots. I never found them very workable in CLSQL (possibly because I didn't understand them well enough), so in Postmodern DAO objects are just simple wrappers for database records, and don't do anything fancy. (Though of course, with some creative method wrapping you could make them do all kinds of bizarre things.) Cheers, Marijn From info at jensteich.de Mon Aug 13 17:28:48 2007 From: info at jensteich.de (Jens Teich) Date: Mon, 13 Aug 2007 19:28:48 +0200 Subject: [postmodern-devel] conditional query building References: <007001c7db95$179a0b90$6b02a8c0@JensSony> Message-ID: <023801c7ddcf$7bfb8b40$6b02a8c0@JensSony> Marijn Haverbeke wrote: > Hello Jens, > > I'm not entirely sure what you want to do here. Do you want the IF to > appear in the query, or the query to be adjusted depending on the > outcome of the IF? In the second case, look into SQL-COMPILE, which > allows the query s-expression to be built at run-time (rather than > compile time, as with the SQL macro). > > Cheers, > Marijn I fount two ways to solve my problem. First is with a macro: (defmacro element (&key guid guid-parent type-id type-not-equal lang) `(postmodern:query (:order-by (:select 'guid 'name 'type-id 'name-css :from 'projekt-elemente :where (:and ,(if guid `(:= 'guid ,guid) t) ,(if guid-parent `(:= 'struct-guid-parent-node ,guid-parent) t) ,(if type-id `(:= 'type-id ,type-id) t) ,(if type-not-equal `(:not (:= 'type-id ,type-not-equal)) t) (:= 'lang-id (or ,lang *default-lang*)))) 'struct-sort-order))) Second is with let: (defun werte (lang merkmal-id &key bereich gruppe reihe) (remove-duplicates ; statt DISTINCT (let ((sql (cond (reihe (postmodern:sql (:= 'guid-reihe reihe))) (gruppe (postmodern:sql (:= 'guid-gruppe gruppe))) (bereich (postmodern:sql (:= 'guid-bereich bereich))) (t "TRUE")))) (postmodern:query (:order-by (:select 'wert :from 'projekt-merkmale-werte :where (:and (:= 'lang-id lang) (:= 'merkmal_id merkmal-id) (:raw sql))) 'wert))) :test #'equal)) Don't know if there is a more direct way to achieve this. Thanks for your library. It rocks. Jens From info at jensteich.de Mon Aug 13 17:29:03 2007 From: info at jensteich.de (Jens Teich) Date: Mon, 13 Aug 2007 19:29:03 +0200 Subject: [postmodern-devel] query with keyword :on References: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> Message-ID: <023901c7ddcf$7d2a6e50$6b02a8c0@JensSony> Marijn Haverbeke wrote: > Hello, > > Are you sure the problem is not just the fact that the tables do not > exist? You didn't post an actual error message, so I'm not sure what > happens. The problem also happens with existing tables. I checked with sbcl and there the result is correct. Don't bother too much about this problem, I can live for the moment expressing the join without :on in the :where clause. Thanks Jens From marijnh at gmail.com Thu Aug 16 07:19:39 2007 From: marijnh at gmail.com (Marijn Haverbeke) Date: Thu, 16 Aug 2007 09:19:39 +0200 Subject: [postmodern-devel] conditional query building In-Reply-To: <023801c7ddcf$7bfb8b40$6b02a8c0@JensSony> References: <007001c7db95$179a0b90$6b02a8c0@JensSony> <023801c7ddcf$7bfb8b40$6b02a8c0@JensSony> Message-ID: Ah, now I see what you mean by using a macro -- that's rather ugly. You could just build the query s-expression with a simple function, and feed it to sql-compile instead... or just use :raw, as you showed. Cheers, Marijn From marijnh at gmail.com Thu Aug 16 07:21:17 2007 From: marijnh at gmail.com (Marijn Haverbeke) Date: Thu, 16 Aug 2007 09:21:17 +0200 Subject: [postmodern-devel] query with keyword :on In-Reply-To: <023901c7ddcf$7d2a6e50$6b02a8c0@JensSony> References: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> <023901c7ddcf$7d2a6e50$6b02a8c0@JensSony> Message-ID: So could you give me the error message? That might give me a chance to figure out what the problem is. Cheers, Marijn From info at jensteich.de Thu Aug 16 23:02:06 2007 From: info at jensteich.de (Jens Teich) Date: Fri, 17 Aug 2007 01:02:06 +0200 Subject: [postmodern-devel] query with keyword :on References: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> <023901c7ddcf$7d2a6e50$6b02a8c0@JensSony> Message-ID: <015b01c7e059$79b5feb0$6e02a8c0@JensSony> Marijn Haverbeke wrote: > So could you give me the error message? That might give me a chance to > figure out what the problem is. > > Cheers, > Marijn Here are two queries which should produce the same result WEBCAT 36 > (postmodern:with-connection ("web_access" "web_access" "***" "localhost") (postmodern:query (:select 'pmw.wert :from (:as 'projekt-merkmale-werte 'pmw) (:as 'projekt-elemente 'pe) :where (:and (:= 'pmw.guid-produkt 'pe.guid-objekt) (:= 'pe.guid "rzt732819vlurc5827955302wwxz8b") (:= 'pmw.merkmal-id "MID1008519") (:= 'pmw.lang-id "de"))))) (("30 N") ("30 N") ("30 N") ("30 N")) WEBCAT 37 > (postmodern:with-connection ("web_access" "web_access" "***" "localhost") (postmodern:query (:select 'pmw.wert :from (:as 'projekt-merkmale-werte 'pmw) :inner-join (:as 'projekt-elemente 'pe) :on (:= 'pmw.guid-produkt 'pe.guid-objekt) :where (:and (:= 'pe.guid "rzt732819vlurc5827955302wwxz8b") (:= 'pmw.merkmal-id "MID1008519") (:= 'pmw.lang-id "de"))))) Error: Database error 42601: syntax error at or near "on" Query: (SELECT pmw.wert FROM projekt_merkmale_werte AS pmw INNER JOIN projekt_elemente AS pe ON (pmw.guid_produkt = pe.guid_objekt), projekt_elemente AS pe, on, (pmw.guid_produkt = pe.guid_objekt) WHERE ((pe.guid = 'rzt732819vlurc5827955302wwxz8b') and (pmw.merkmal_id = 'MID1008519') and (pmw.lang_id = 'de'))) Jens From tozkanli2023 at gmail.com Fri Aug 17 06:23:29 2007 From: tozkanli2023 at gmail.com (=?UTF-8?Q?TARIK_=C3=96ZKANLI?=) Date: Fri, 17 Aug 2007 09:23:29 +0300 Subject: [postmodern-devel] query with keyword :on In-Reply-To: <015b01c7e059$79b5feb0$6e02a8c0@JensSony> References: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> <023901c7ddcf$7d2a6e50$6b02a8c0@JensSony> <015b01c7e059$79b5feb0$6e02a8c0@JensSony> Message-ID: hi, first of all sorry for the trivial question. I want to install postmodern with Allegro CL 8.0 Free express edition but i could not succeed. I think there is a problem with asdf/asdf-install library but i am not sure. What may be the reason? Thank you in advance. On 17/08/07, Jens Teich wrote: > > Marijn Haverbeke wrote: > > So could you give me the error message? That might give me a chance to > > figure out what the problem is. > > > > Cheers, > > Marijn > > Here are two queries which should produce the same result > > WEBCAT 36 > (postmodern:with-connection ("web_access" "web_access" "***" > "localhost") > (postmodern:query > (:select 'pmw.wert > :from (:as 'projekt-merkmale-werte 'pmw) > (:as 'projekt-elemente 'pe) > :where (:and > (:= 'pmw.guid-produkt 'pe.guid-objekt) > (:= 'pe.guid "rzt732819vlurc5827955302wwxz8b") > (:= 'pmw.merkmal-id "MID1008519") > (:= 'pmw.lang-id "de"))))) > (("30 N") ("30 N") ("30 N") ("30 N")) > > WEBCAT 37 > (postmodern:with-connection ("web_access" "web_access" "***" > "localhost") > (postmodern:query > (:select 'pmw.wert > :from (:as 'projekt-merkmale-werte 'pmw) > :inner-join (:as 'projekt-elemente 'pe) > :on (:= 'pmw.guid-produkt 'pe.guid-objekt) > :where (:and > (:= 'pe.guid "rzt732819vlurc5827955302wwxz8b") > (:= 'pmw.merkmal-id "MID1008519") > (:= 'pmw.lang-id "de"))))) > > Error: Database error 42601: syntax error at or near "on" > Query: (SELECT pmw.wert FROM projekt_merkmale_werte AS pmw INNER JOIN > projekt_elemente AS pe ON (pmw.guid_produkt = pe.guid_objekt), > projekt_elemente AS pe, on, (pmw.guid_produkt = pe.guid_objekt) WHERE (( > pe.guid = 'rzt732819vlurc5827955302wwxz8b') and (pmw.merkmal_id = > 'MID1008519') and (pmw.lang_id = 'de'))) > > Jens > _______________________________________________ > postmodern-devel mailing list > postmodern-devel at common-lisp.net > http://common-lisp.net/cgi-bin/mailman/listinfo/postmodern-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From info at jensteich.de Fri Aug 17 11:19:19 2007 From: info at jensteich.de (Jens Teich) Date: Fri, 17 Aug 2007 13:19:19 +0200 Subject: [postmodern-devel] with-connection problem Message-ID: <01a301c7e0c0$7906cd20$6e02a8c0@JensSony> What's wrong here? Tested with LW and SBCL. Thanks Jens POMO> (with-connection ("web_access" "web_access" "***" "localhost") (query (:select '* :from 'dokumente-files))) (("s5s732006l9t5i0ai3a308281gwdh5 " "z_z15p02" "Bilddata/AZ/Pdf/Az15_16/baumuste" "pdf" 1914355) ...... POMO> (defparameter *db* '("web_access" "web_access" "***" "localhost")) *DB* POMO> (with-connection *db* (query (:select '* :from 'dokumente-files))) error while parsing arguments to DEFMACRO WITH-CONNECTION: bogus sublist *DB* to satisfy lambda-list (DATABASE USER PASSWORD HOST &KEY (PORT 5432) POOLED-P) [Condition of type SB-KERNEL::DEFMACRO-BOGUS-SUBLIST-ERROR] From ryszard.szopa at gmail.com Fri Aug 17 15:05:01 2007 From: ryszard.szopa at gmail.com (Ryszard Szopa) Date: Fri, 17 Aug 2007 17:05:01 +0200 Subject: [postmodern-devel] with-connection problem In-Reply-To: <01a301c7e0c0$7906cd20$6e02a8c0@JensSony> References: <01a301c7e0c0$7906cd20$6e02a8c0@JensSony> Message-ID: <19e19e410708170805o4a28f882u61b4f783c0be9fab@mail.gmail.com> On 8/17/07, Jens Teich wrote: > What's wrong here? Tested with LW and SBCL. > POMO> (with-connection ("web_access" "web_access" "***" "localhost") > (query (:select '* :from 'dokumente-files))) > (("s5s732006l9t5i0ai3a308281gwdh5 " "z_z15p02" > "Bilddata/AZ/Pdf/Az15_16/baumuste" "pdf" 1914355) > ...... > > POMO> (defparameter *db* '("web_access" "web_access" "***" "localhost")) > *DB* > > POMO> (with-connection *db* > (query (:select '* :from 'dokumente-files))) > > error while parsing arguments to DEFMACRO WITH-CONNECTION: > bogus sublist > *DB* > to satisfy lambda-list > (DATABASE USER PASSWORD HOST &KEY (PORT 5432) POOLED-P) > [Condition of type SB-KERNEL::DEFMACRO-BOGUS-SUBLIST-ERROR] Postmodern's macro WITH-CONNECTION expects its connection specification argument to be an unquoted list (it doesn't evaluate it). The easiest solution to your problem may be writing a macro with-default-connection: (defmacro with-default-connection (&body body) `(with-connection ("web_access" "web_access" "***" "localhost") , at body)) Another possibility would be to change Postmodern's with-connection and make it a macro interface to a function: (defun with-connection-fun (connection-spec what-to-do) "Functional under the macro WITH-CONNECTION." (let ((postmodern:*database* (apply #'postmodern:connect connection-spec))) (unwind-protect (progn (funcall what-to-do)) (postmodern:disconnect postmodern:*database*)))) ;; This is postmodern's WITH-CONNECTION modified to use the functional ;; interface. (defmacro with-connection ((database user password host &key (port 5432) pooled-p) &body body) "Binds *database* to a new connection and runs body in that scope." `(with-connection-fun '(,database ,user ,password ,host :port ,port :pooled-p ,pooled-p) (lambda () (progn , at body)))) Then you can do something like (with-connection-fun *DB* (lambda () (query (:select '* :from 'dokumente-files)))) if you really want it. This approach make also a lot easier writing custom with-*-connection macros (like with-object-connection and so on). Marijn: maybe you could consider changing Postmodern's with-connection as I've described above? Bests, -- Richard -- http://szopa.tasak.gda.pl/ From ryszard.szopa at gmail.com Fri Aug 17 15:06:30 2007 From: ryszard.szopa at gmail.com (Ryszard Szopa) Date: Fri, 17 Aug 2007 17:06:30 +0200 Subject: [postmodern-devel] with-connection problem In-Reply-To: <19e19e410708170805o4a28f882u61b4f783c0be9fab@mail.gmail.com> References: <01a301c7e0c0$7906cd20$6e02a8c0@JensSony> <19e19e410708170805o4a28f882u61b4f783c0be9fab@mail.gmail.com> Message-ID: <19e19e410708170806k77d07254vb3679627bb7a713e@mail.gmail.com> On 8/17/07, Ryszard Szopa wrote: > (defun with-connection-fun (connection-spec what-to-do) > "Functional under the macro WITH-CONNECTION." Should be: "Function under the macro..." > (let ((postmodern:*database* (apply #'postmodern:connect connection-spec))) > (unwind-protect (progn (funcall what-to-do)) > (postmodern:disconnect postmodern:*database*)))) -- http://szopa.tasak.gda.pl/ From nablaone at gmail.com Sun Aug 19 07:38:42 2007 From: nablaone at gmail.com (=?UTF-8?Q?Rafa=C5=82_Strzali=C5=84ski?=) Date: Sun, 19 Aug 2007 09:38:42 +0200 Subject: [postmodern-devel] with-connection problem In-Reply-To: <19e19e410708170805o4a28f882u61b4f783c0be9fab@mail.gmail.com> References: <01a301c7e0c0$7906cd20$6e02a8c0@JensSony> <19e19e410708170805o4a28f882u61b4f783c0be9fab@mail.gmail.com> Message-ID: On 8/17/07, Ryszard Szopa wrote: > > This approach make also a lot easier writing custom with-*-connection > macros (like with-object-connection and so on). > > Marijn: maybe you could consider changing Postmodern's with-connection > as I've described above? or to something like this one: (defvar *connection-spec* (list "db" "user" "pass" "host" :pooled-p t)) (defmacro with-db (&body body) `(let ((*database* (apply 'connect *connection-spec*))) (unwind-protect (progn , at body) (disconnect *database*)))) -- Cheers, Rafal Strzalinski (nabla) http://nablaone.net From marijnh at gmail.com Sun Aug 19 11:39:42 2007 From: marijnh at gmail.com (Marijn Haverbeke) Date: Sun, 19 Aug 2007 13:39:42 +0200 Subject: [postmodern-devel] query with keyword :on In-Reply-To: References: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> <023901c7ddcf$7d2a6e50$6b02a8c0@JensSony> <015b01c7e059$79b5feb0$6e02a8c0@JensSony> Message-ID: Hi Tarik, (Don't reply to a message when you're opening a new topic -- it confuses mail readers.) You will need ASDF to run Postmodern, but I think that should come included with Allegro (does it? any other Allegro users on this list?). ASDF-Install makes it easy to download and install the library, but is not necessary. Download the .tar.gz file from the library page, unpack it somewhere on your system (use a tool like WinRAR if you're on Windows), and create a file-system link to the .asd files in some directory that your ADSF searches (the variable asdf:*central-repository* should contain a list of such directories.) After this, doing (asdf:oos 'asdf:load-op :postmodern) should load the library. Cheers, Marijn From marijnh at gmail.com Sun Aug 19 11:45:52 2007 From: marijnh at gmail.com (Marijn Haverbeke) Date: Sun, 19 Aug 2007 13:45:52 +0200 Subject: [postmodern-devel] query with keyword :on In-Reply-To: <015b01c7e059$79b5feb0$6e02a8c0@JensSony> References: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> <023901c7ddcf$7d2a6e50$6b02a8c0@JensSony> <015b01c7e059$79b5feb0$6e02a8c0@JensSony> Message-ID: Aha, I see the syntax error now -- might be some slight difference in the way LOOP works on LispWorks. But I'm on a public computer somewhere, and will not be near any machines running Lisp in the next weeks, so I can't really debug this for you. If you want to solve this, you can try digging into the code in s-sql/s-sql.lisp that produces such queries, and see where it goes wrong (shouldn't be too hard). Or maybe someone else on the list wants to take a quick look? Cheers, Marijn From marijnh at gmail.com Sun Aug 19 11:48:53 2007 From: marijnh at gmail.com (Marijn Haverbeke) Date: Sun, 19 Aug 2007 13:48:53 +0200 Subject: [postmodern-devel] with-connection problem In-Reply-To: <19e19e410708170805o4a28f882u61b4f783c0be9fab@mail.gmail.com> References: <01a301c7e0c0$7906cd20$6e02a8c0@JensSony> <19e19e410708170805o4a28f882u61b4f783c0be9fab@mail.gmail.com> Message-ID: On 8/17/07, Ryszard Szopa wrote: > Marijn: maybe you could consider changing Postmodern's with-connection > as I've described above? Will be looked into when I'm back at my own place (which won't be for a while). It would be an incompatible change though, I'll probably just add an alternative with another name instead. Cheers, Marijn From tozkanli2023 at gmail.com Mon Aug 20 06:49:28 2007 From: tozkanli2023 at gmail.com (=?UTF-8?Q?TARIK_=C3=96ZKANLI?=) Date: Mon, 20 Aug 2007 09:49:28 +0300 Subject: [postmodern-devel] query with keyword :on In-Reply-To: References: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> <023901c7ddcf$7d2a6e50$6b02a8c0@JensSony> <015b01c7e059$79b5feb0$6e02a8c0@JensSony> Message-ID: ok.i am sorry for that. thank you for the help. cheers On 19/08/07, Marijn Haverbeke wrote: > > Hi Tarik, > > (Don't reply to a message when you're opening a new topic -- it > confuses mail readers.) > > You will need ASDF to run Postmodern, but I think that should come > included with Allegro (does it? any other Allegro users on this > list?). ASDF-Install makes it easy to download and install the > library, but is not necessary. Download the .tar.gz file from the > library page, unpack it somewhere on your system (use a tool like > WinRAR if you're on Windows), and create a file-system link to the > .asd files in some directory that your ADSF searches (the variable > asdf:*central-repository* should contain a list of such directories.) > After this, doing (asdf:oos 'asdf:load-op :postmodern) should load the > library. > > Cheers, > Marijn > _______________________________________________ > postmodern-devel mailing list > postmodern-devel at common-lisp.net > http://common-lisp.net/cgi-bin/mailman/listinfo/postmodern-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From info at jensteich.de Mon Aug 20 21:23:05 2007 From: info at jensteich.de (Jens Teich) Date: Mon, 20 Aug 2007 23:23:05 +0200 Subject: [postmodern-devel] query with keyword :on References: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> <023901c7ddcf$7d2a6e50$6b02a8c0@JensSony> <015b01c7e059$79b5feb0$6e02a8c0@JensSony> Message-ID: <002a01c7e370$4f0af930$6e02a8c0@JensSony> Marijn Haverbeke wrote: > Aha, I see the syntax error now -- might be some slight difference in > the way LOOP works on LispWorks. But I'm on a public computer > somewhere, and will not be near any machines running Lisp in the next > weeks, so I can't really debug this for you. If you want to solve > this, you can try digging into the code in s-sql/s-sql.lisp that > produces such queries, and see where it goes wrong (shouldn't be too > hard). Or maybe someone else on the list wants to take a quick look? > > Cheers, > Marijn Hi Marijn, I looked into the code and found the function expand-join to be a candidate for cause of the problems: (defun expand-joins (args) "Helper for the select operator. Turns the part following :from into the proper SQL syntax for joining tables." (labels ((is-join (x) (member x '(:left-join :right-join :inner-join :cross-join)))) (when (null args) (error "Empty :from clause in select")) (when (is-join (car args)) (error ":from clause starts with a join: ~A" args)) (loop :for table :on args :for first = t :then nil :append (cond ((is-join (car table)) (destructuring-bind (join name on clause) (subseq table 0 4) (setf table (cdddr table)) ;; debug start (print (list "table" table)) ;; debug end (unless (and (eq on :on) clause) (error "Incorrect join form in select.")) `(" " ,(ecase join (:left-join "LEFT") (:right-join "RIGHT") (:inner-join "INNER") (:cross-join "CROSS")) " JOIN " ,@(sql-expand name) " ON " ,@(sql-expand clause)))) (t `(,@(if first () '(", ")) ,@(sql-expand (car table)))))))) I traced it: S-SQL 68 > (trace expand-joins) (EXPAND-JOINS) S-SQL 69 > (sql (:select '* :from 't1 :inner-join 't2 :on (:= 't1.id 't2.id))) 0 EXPAND-JOINS > ... >> ARGS : ((QUOTE T1) :INNER-JOIN (QUOTE T2) :ON (:= (QUOTE T1.ID) (QUOTE T2.ID))) 0 EXPAND-JOINS < ... << VALUE-0 : ("t1" " " "INNER" " JOIN " "t2" " ON " "(" "t1.id" " = " "t2.id" ")" ", " "t2" ", " "on" ", " "(" "t1.id" " = " "t2.id" ")") "(SELECT * FROM t1 INNER JOIN t2 ON (t1.id = t2.id), t2, on, (t1.id = t2.id))" For me it looks a bit strange to declare a loop variable | :for table :on args and later on to manipulate this variable with setf | (setf table (cdddr table)) and indeed LispWorks and SBCL behave differently with such an expression LW> (loop for item on '(1 2 3 4 5) collect (progn (setf item (cddr item)) item)) => ((3 4 5) (4 5) (5) NIL NIL) SBCL> (loop for item on '(1 2 3 4 5) collect (progn (setf item (cddr item)) item)) => ((3 4 5) NIL) where LispWorks produces 'too much' output as in the original problem. Jens From marijnh at gmail.com Sat Aug 25 10:46:55 2007 From: marijnh at gmail.com (Marijn Haverbeke) Date: Sat, 25 Aug 2007 12:46:55 +0200 Subject: [postmodern-devel] query with keyword :on In-Reply-To: <002a01c7e370$4f0af930$6e02a8c0@JensSony> References: <010401c7dc2e$20e58eb0$6b02a8c0@JensSony> <023901c7ddcf$7d2a6e50$6b02a8c0@JensSony> <015b01c7e059$79b5feb0$6e02a8c0@JensSony> <002a01c7e370$4f0af930$6e02a8c0@JensSony> Message-ID: Hi, Thanks for tracing the problem. If you have a fix, could you send me a patch (as created by 'darcs send -o fix.patch'), so I can apply it to the repository? Marijn From attila.lendvai at gmail.com Mon Aug 27 00:49:51 2007 From: attila.lendvai at gmail.com (Attila Lendvai) Date: Mon, 27 Aug 2007 02:49:51 +0200 Subject: [postmodern-devel] postmodern, pg, cl-rdbms In-Reply-To: References: Message-ID: you can find the following patch at: darcs pull http://common-lisp.net/project/cl-wdim/darcs/postmodern Tue Aug 21 15:34:46 CEST 2007 attila.lendvai at gmail.com * Use ironclad for md5 hashing (much better optimized) we were profiling our code and saw that postgres connecting was among the consumers. the main bottleneck was the md5 hashing/printing, so tried with ironclad and it was a lot faster. you may consider moving to ironclad and then pulling the patch. i hope you'll like it. at your service, -- attila From ryszard.szopa at gmail.com Tue Aug 28 15:49:28 2007 From: ryszard.szopa at gmail.com (Ryszard Szopa) Date: Tue, 28 Aug 2007 17:49:28 +0200 Subject: [postmodern-devel] Submarine announcement Message-ID: <19e19e410708280849q41a1a64dwd893085f77f39f60@mail.gmail.com> Hello Marijn and Postmodern users, I was a bit dissatisfied with Postmodern's DAO system and lack of support for foreign keys. At first, I wrote just a patch that added support for foreign keys, but it turned the macro DEFTABLE into something that had more than 100 lines and was pretty unmaintainable. So, I left Postmodern's sources alone and wrote a library over it, something between Postmodern and an object persistency library. I've used it in some of my projects at work, and now I decided to make it open source. In a couple of days I'll start it a common-lisp.net project and announce it to c.l.l. In the meantime, I will be very grateful for any comments. I encourage you to at least take a look at the example file: http://bender.streamtech.nl/darcs/submarine/doc/example.lisp Here are the contents of my README file: Submarine is a Common Lisp library that's somewhere between a PostgreSQL library an an object persistency system. It uses Postmodern to communicate with the database. The basic idea is that you create your classes in the metaclass DB-CLASS and submarine cares about creating SQL tables or, if the tables already exist, checking if they conform to the provided specification. Moreover, Submarine supports an intuitive way of expressing both one-to-many and many-to-many relations. Getting submarine ================= At the moment there's only a darcs repository available: darcs pull http://bender.streamtech.nl/darcs/submarine/ You will also need my mop-utilities, which may be incorporated into submarine in the close future: darcs get http://bender.streamtech.nl/darcs/mop-utils Dependencies ============ Submarine depends on Postmodern and Iterate. It uses also my library of MOP utilities, MOP-UTILS, which may become a separate library in the future. On platforms other than SBCL, mop-utils needs Closer-mop. License ======= Submarine is released under a BSD-like license. Which approximately means you can use the code in whatever way you like, except for passing it off as your own or releasing a modified version without indication that it is not the original. Relation to Postmodern ====================== Submarine started as a patch that added, among others, foreign keys support to Postmodern. This meant hacking the DEFTABLE macro and TABLE and TABLEFIELD classes. After some time I realized that my modified Postmodern macros had become far too large and heavy to be easy maintainable. So, I decided to leave Postmodern's code as it was and write a separate library. Introduction for Postmodern users ================================= Submarine tries to keep as much as possible of Postmodern's original API. I use the same terminology, and functions with similar names will probably do very similar things. My purpose was twofold. First of all, I wanted to make porting programs using Postmodern to Submarine easy. Secondly, this would allow me to use some of Marijn Haverbeke's superb documentation nearly without any changes. Main differences between Postmodern and Submarine: * You don't have to create DAO (database access object) classes and SQL tables separately. You just create classes belonging to a certain metaclass, and the library cares of the rest. * If the table with an appropriate name exists in the database, Submarine will test if it has columns with the right names and types. If a column does not exist or has a wrong type, Submarine will offer the user a possibility to fix it. Submarine will warn, but do nothing about any additional columns in the table. * Each DB-CLASS class has its own connection specification. This means that you can just access your objects, without wrapping them in a WITH-CONNECTION macro, and they will care about setting the right connection. * DAO is a basis class for DB-CLASS classes, and methods that are supposed to work on an object of any DB-CLASS class use DAO as a dispatch type. Of course, you don't have to use DAO as a base class, but it makes a lot of things easier. * Submarine supports foreign keys. If you define a DB-CLASS class with a slot whose type is another DB-CLASS, it is treated as foreign key and an appropriate constraint is added to the database. * Submarine provides a function to retrieve all the elements of a given type standing in a many-to-one relation with some DAO object. * The DEF-MANY-TO-MANY macro defines a many-to-many relation between two classes and creates methods appropriate to their retrieval (it creates a link table in the database). * DB-CLASS slots have an additional attribute TRANSIENT. If you set it to a non-NIL value, it will behave just as a STANDARD-SLOT-DEFINITION and will be ignored in database related operations. * Submarine uses MOP rather than macros to achieve its purposes. This makes it easier to maintain and to extend. At the moment there's no real documentation apart from docstrings, but there's a poor man's tutorial in the file http://bender.streamtech.nl/darcs/submarine/doc/example.lisp (this should give you a pretty good overview of the possibilities of Submarine. Bests, -- Richard -- http://szopa.tasak.gda.pl/ From nablaone at gmail.com Tue Aug 28 18:18:19 2007 From: nablaone at gmail.com (=?UTF-8?Q?Rafa=C5=82_Strzali=C5=84ski?=) Date: Tue, 28 Aug 2007 20:18:19 +0200 Subject: [postmodern-devel] Submarine announcement In-Reply-To: <19e19e410708280849q41a1a64dwd893085f77f39f60@mail.gmail.com> References: <19e19e410708280849q41a1a64dwd893085f77f39f60@mail.gmail.com> Message-ID: On 8/28/07, Ryszard Szopa wrote: > Hello Marijn and Postmodern users, > > I was a bit dissatisfied with Postmodern's DAO system and lack of > support for foreign keys. At first, I wrote just a patch that added > support for foreign keys... Hi, Is there any way to separate DAO definition and db connection spec? Keeping connection spec in one place (global variable) makes deployment easier. BTW, nice password ;-) -- Cheers, Rafal Strzalinski (nabla) http://nablaone.net From ryszard.szopa at gmail.com Tue Aug 28 23:21:36 2007 From: ryszard.szopa at gmail.com (Ryszard Szopa) Date: Wed, 29 Aug 2007 01:21:36 +0200 Subject: [postmodern-devel] Submarine announcement In-Reply-To: References: <19e19e410708280849q41a1a64dwd893085f77f39f60@mail.gmail.com> Message-ID: <19e19e410708281621i721f5f17nff4065a0fe0aab16@mail.gmail.com> On 8/28/07, Rafa? Strzali?ski wrote: > Is there any way to separate DAO definition and db connection spec? > Keeping connection spec in one place (global variable) makes > deployment easier. Well, the idea behind each class having its own connection spec is that I would like to allow each class to be connecting another database. I don't know if this is the best approach (after all, this is not the most common a situation), and maybe I will rethink it. Personally, I usually wrap my dao defnitions into a macro with the right connection spec, like the following: (defmacro defdao-example (name supers &body body) "Wrapper macro for defining a class inheriting from DAO with the metaclass set to HTML and the right connection-spec." `(defdao ,name ,supers , at body (:connection-spec "submarine-test" "richard" "dupa" "localhost"))) > BTW, nice password ;-) Well, I guess it is one of the glorious Polish traditions (-; Bests, -- Richard -- http://szopa.tasak.gda.pl/ From marijnh at gmail.com Wed Aug 29 10:17:20 2007 From: marijnh at gmail.com (Marijn Haverbeke) Date: Wed, 29 Aug 2007 12:17:20 +0200 Subject: [postmodern-devel] Submarine announcement In-Reply-To: <19e19e410708280849q41a1a64dwd893085f77f39f60@mail.gmail.com> References: <19e19e410708280849q41a1a64dwd893085f77f39f60@mail.gmail.com> Message-ID: Hey Ryszard, Great work! I've only checked it out globally, but it looks very nice. I'm always a big fan of keeping stuff separate, rather than integrating things into big blobs of code, so I'm glad you managed to make this a separate library. Have you found a way around the issues postgres has with creation and deletion of tables that have foreign keys referring to each other? (i.e. it will not let you put your database in an incorrect state) Cheers, Marijn From ryszard.szopa at gmail.com Thu Aug 30 09:13:26 2007 From: ryszard.szopa at gmail.com (Ryszard Szopa) Date: Thu, 30 Aug 2007 11:13:26 +0200 Subject: [postmodern-devel] Submarine announcement In-Reply-To: References: <19e19e410708280849q41a1a64dwd893085f77f39f60@mail.gmail.com> Message-ID: <19e19e410708300213i43bfea1av430e6004865f90b6@mail.gmail.com> On 8/29/07, Marijn Haverbeke wrote: > Hey Ryszard, > > Great work! I've only checked it out globally, but it looks very nice. Thanks! > I'm always a big fan of keeping stuff separate, rather than > integrating things into big blobs of code, so I'm glad you managed to > make this a separate library. Have you found a way around the issues > postgres has with creation and deletion of tables that have foreign > keys referring to each other? (i.e. it will not let you put your > database in an incorrect state) Not really. I also have a problem if a class refers to a not-yet-existing class/table in its foreign key: Postgres will stubbornly refuse to create it. At the moment I am working on a workaround for it. I want to separate the foreign key stuff from the table creation, i.e. I want to first create the table, and then add constraints to it (this would also allow me to check if the constraints are right when the table already exists). I plan to put the code for setting foreign key constraints into a lambda, and wrap its funcall by handler-case. If everything goes right, this is the end of the story for that lambda. If the handler-case catches a PostgreSQL error, then the lambda is stored somewhere. Then, when a class of db-class is created, it tries to run all the canned constraints available. There are two things about this approach I am not so happy about. First, this means adding an additional attribute to DB-CLASS-SLOT-DEFINITION. Secondly, I am not really sure what is the best way of dealing with classes that have delayed constraints that hadn't been fired (like when, for example, the user had forgotten to write the definition of the class referred to). Do you feel this approach is sensible? Or maybe anybody has a better idea? Bests, -- Richard -- http://szopa.tasak.gda.pl/