Squeryl dynamic join clauses

只谈情不闲聊 提交于 2019-12-25 07:35:10

问题


What I'm looking for seems fairly common but I can't seem to figure it out through the Squeryl api. I need to have a conditional piece to my on statement for a join.

def getAllJoined(
  hasFallback:Option[String] = None
  ):List[(Type1,Type2)] = transaction{
  join(mainTable,
    table2,
    table3,
    table3,
    table4.leftOuter,
    table4.leftOuter,
    table5,
    table6)((main, attr1, attr2, attr3, attr4, attr5, attr6, attr7) =>
    select(main,attr1,attr2,attr3,attr4,attr5,attr6,attr7)
    on(
      //if(hasFallback.isDefined) (main.fallBack).isNotNull else 1 === 1.inhibitWhen(true)
      (main.attr1Col === attr1.id) ,
      (main.attr2Col === attr2.id) ,
      (main.attr3Col === attr3.id) ,
      (main.attr4Col === attr4.map(_.id)) ,
      (main.attr5Col === attr5.map(_.id)) ,
      (main.attr6Col === attr6.id) ,
      (main.attr7Col === attr7.id)
      )
  ).toList

I'm not sure how I could get this. I've thought about things like tacking on another on, or doing what I have commented here.

The bottom line is basically if I have this hasFallback flag on, I need to only return objects that have this column not null (defined). Otherwise if the hasFallback flag isn't there, ignore if it's defined or not.

EDIT: It looks like the on method can only take seven parameters. Is there a way around this seven parameter limit?

Also, type mismatch; found : org.squeryl.dsl.boilerplate.JoinQueryYield6[myTuple] required: org.squeryl.dsl.boilerplate.JoinQueryYield7[?] So apparently I'm being forced to have 7 some reason no matter what? No more or no less.

Directly from the squeryl site

If a join has N arguments, the ‘on’ function must take N-1 arguments, the i’th ‘on’ condition corresponds to the i’th table expression :

join(T, A1, A2,... AN)((a1,a2,...,aN) =>
  ...
  on(...condition for a1...,...condition for a2...,......condition for aN..., )
)

SOLUTION: For anyone else that landed here with the same problem, here is the solution using a where clause.

...table6)((main, attr1, attr2, attr3, attr4, attr5, attr6, attr7) =>
where(
    main.fallBack.isNotNull.inhibitWhen(!hasFallback.isDefined)
    )
    select(main,attr1,attr2,attr3,attr4,attr5,attr6,attr7)...

回答1:


If you are simply looking to add a conditional to your where clause, you can do something like this:

on(
   t1.secondary === t2.id and
   (if(hasFallback.isDefined) t1.fallback.isNotNull else 1 === 1.inhibitWhen(true))
)

The inhibitWhen clause should always prevent the output of 1 === 1 from showing up in the actual SQL, but it allows your if/else to return a LogicalBoolean.




回答2:


There is a talk related to a similar question on github and a google group:

https://github.com/max-l/Squeryl/pull/168

https://github.com/max-l/Squeryl/pull/144

https://groups.google.com/forum/#!topic/squeryl/BBAXbtRq9v4

If you're using squeryl-0.9.5-6, then you should find a way out by your own. I chose to do (a similar task) the following way:

    /** thin wrappwer with no runtime cost */
    implicit class RichLogicalBoolean(val e: LogicalBoolean) extends AnyVal {
        def and(condition: Boolean, other: LogicalBoolean) = if (condition) other and e else e
    }

after this, I can write a code like:

t1.secondary === t2.id and
    (yourCondition, t1.fallback.isNotNull)


来源:https://stackoverflow.com/questions/17222246/squeryl-dynamic-join-clauses

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!