xowiki::FormPage proc filter_expression

 xowiki::FormPage[i] filter_expression

Defined in

Testcases:
xowiki_test_cases, xowiki
Source code:
#ns_log notice "filter_expression '$input_expr' $logical_op"

#
# example for unless: wf_current_state = closed|accepted || x = 1
#

array set tcl_op {= eq < < > > >= >= <= <=}
array set sql_op {= =  < < > > >= >= <= <=}
array set op_map {
  contains,sql {$lhs_var like '%$sql_rhs%'}
  contains,tcl {{$rhs} in $lhs_var}
  matches,sql {$lhs_var like '$sql_rhs'}
  matches,tcl {[string match "$rhs" $lhs_var]}
}

set tcl_clause [list]
set h_clause [list]
set vars [list]
set sql_clause [list]
foreach clause [split [string map [list $logical_op \x00] $input_expr] \x00] {
  if {[regexp {^(.*[^<>])\s*([=<>]|<=|>=|contains|matches)\s*([^=]?.*)$} $clause _ lhs op rhs_expr]} {
    set lhs [string trim $lhs]
    set rhs_expr [string trim $rhs_expr]
    if {[string index $lhs 0] eq "_"} {
      #
      # Comparison with field names starting with "_"
      #
      set lhs_var [string range $lhs 1 end]
      set rhs [split $rhs_expr |]
      set sql_rhs [:sql_value $rhs]
      #:msg "check op '$op' in SQL [info exists op_map($op,sql)]"
      if {[info exists op_map($op,sql)]} {
        lappend sql_clause [subst -nocommands $op_map($op,sql)]
        if {[info exists :db_slot($lhs_var)]} {
          set lhs_var "\[set :$lhs_var\]"
          lappend tcl_clause [subst -nocommands $op_map($op,tcl)]
        } else {
          :msg "ignoring unknown variable '$lhs_var' in expression (have '[lsort [array names :db_slot]]')"
        }
      } elseif {[llength $rhs]>1} {
        lappend sql_clause "$lhs_var in ([ns_dbquotelist $rhs])"
        # the following statement is only needed, when we rely on tcl-only
        lappend tcl_clause "\[lsearch -exact {$rhs} \[:property $lhs\]\] > -1"
      } else {
        lappend sql_clause "$lhs_var $sql_op($op) '$rhs'"
        # the following statement is only needed, when we rely on tcl-only
        lappend tcl_clause "\[:property $lhs\] $tcl_op($op) {$rhs}"
      }
    } else {
      #
      # Field names referring to instance attributes.
      #
      set hleft [::xowiki::hstore::double_quote $lhs]
      lappend vars $lhs ""
      if {$op eq "contains"} {
        #make approximate query
        set lhs_var instance_attributes
        set sql_rhs $rhs_expr
        lappend sql_clause [subst -nocommands $op_map($op,sql)]
      }
      set lhs_var "\[dict get \$__ia $lhs\]"
      set tcl_rhs_clauses {}
      foreach rhs [split $rhs_expr |] {
        set sql_rhs [:sql_value $rhs]
        if {[info exists op_map($op,tcl)]} {
          lappend tcl_rhs_clauses [subst -nocommands $op_map($op,tcl)]
        } else {
          lappend tcl_rhs_clauses "$lhs_var $tcl_op($op) {$rhs}"
        }
        if {$op eq "="} {
          # TODO: think about a solution for other operators with
          # hstore maybe: extracting it by a query via hstore and
          # compare in plain SQL
          lappend h_clause "$hleft=>[::xowiki::hstore::double_quote $rhs]"
        }
      }
      lappend tcl_clause ([join $tcl_rhs_clauses ||])
    }
  } else {
    :msg "ignoring $clause"
  }
}
if {[llength $tcl_clause] == 0} {
  set tcl_clause [list true]
}
#:msg sql=$sql_clause,tcl=$tcl_clause
set result [list  tcl [join $tcl_clause $logical_op]  h [join $h_clause ,]  vars $vars  sql $sql_clause]
#:msg "filter_expression -sql $sql inp '$input_expr' log '$logical_op' -> $result"

return $result
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: