Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The project+ fn #87

Open
r0man opened this issue Mar 26, 2011 · 7 comments
Open

The project+ fn #87

r0man opened this issue Mar 26, 2011 · 7 comments
Labels

Comments

@r0man
Copy link
Collaborator

r0man commented Mar 26, 2011

Sometimes I want to add artificial fields to a query but can't
use project, because it overwrites previous selections. What
about adding something like:

(defn project+
  [relation fields]
  (assoc relation :tcols (concat (:tcols relation) fields)))

to ClojureQL? With this function I can add a "distance
calculation" to the query with something like this:

(-> spots-with-address
    (select-in-bounding-box :spots.location bounding-box)
    (project+ [[(str "distance(spots.location, ST_GeomFromText('" (make-point-2d 0 0) "'))") :as :distance]])
    (sort [:distance]))

Thoughts? Suggestions?

@LauJensen
Copy link
Owner

We debated this quite a bit when doing the initial implementation. What it came down to is that project is by definition non-additive. Since I cant offer deeper insights into RA than the creators of it, I decided to adhere by their standards. I think this is a good example of how easy it is to extend ClojureQL, without the need to modify ClojureQL itself.

Your thoughts?

@r0man
Copy link
Collaborator Author

r0man commented Mar 27, 2011

I can understand that you want to keep it clean. On the other
hand I can see me copying this fn to all of my ClojureQL
projects. And I hate copying :) Maybe somthing for
clojureql.utils?

@LauJensen
Copy link
Owner

Thats not a bad idea. We really should compile a list of things for cql.utils

@ninjudd
Copy link
Collaborator

ninjudd commented Mar 27, 2011

What about making it so this does what you want?

(project [:* ["distance(...)" :as :distance]])

@ninjudd
Copy link
Collaborator

ninjudd commented Mar 27, 2011

Agreed. I think :* should mean: all columns projected so far. If you want all columns in a particular table, then use :spots.*

@ninjudd
Copy link
Collaborator

ninjudd commented Mar 27, 2011

Oops. Was trying to fix formatting on r0man's post, but accidentally hit delete (fingers are too big for my iPhone).

@ninjudd
Copy link
Collaborator

ninjudd commented Mar 27, 2011

Here is r0man's message:

I tried this, but the spots-with-address is actually defined like this:

(def spots-with-address
  (-> spots
    (join (project (table :countries) [[:name :as :address_country]])
          (where (= :spots.country_id :countries.id)))
    (join (project (table :regions) [[:name :as :address_region]])
          (where (= :spots.region_id :regions.id)))
    (outer-join (project (table :addresses)
                         [[:locality :as :address_locality]
                          [:postal_code :as :address_postal_code]
                          [:street_address :as :address_street_address]
                          [:extended_address :as :address_extended_address]])
                :left (where (geo= :spots.location :addresses.location)))))

When using spots-with-address defined like above and applying the project operator in another function like this:

(project [:* ["distance(...)" :as :distance]])

... it selects everything from the spots table (spots.*) and the distance. All the other columns I have joined above get thrown away.

The shortcut :* in this example is really :spots._. Applying :_ doesn't honor my previous selection, but starts back looking at the spots table and not my new relation
spots-with-address.

I think since :* is not defined in RA (you give all the attributes you want to project) it's questionalble if the shortcut :* applys to the relation (spots-with-address) at hand or the original one (spots). I think the first one is the route to true composability ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants