Skip to content

Commit

Permalink
new condition system, little fixes
Browse files Browse the repository at this point in the history
The old condition system was too difficult to understand (i think).
Now we have a more verbose, but (in my opinion) easiert to understand
condition system. Don't worry, I'll provide shortcuts.
  • Loading branch information
fredreichbier committed Feb 14, 2009
1 parent e962488 commit 59aa4a2
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 75 deletions.
144 changes: 89 additions & 55 deletions iorm/Condition.io
@@ -1,76 +1,110 @@
ConditionError := Exception clone

onlyMessage := method(msg,
msg clone setNext(nil)
)

parseMessage := method(table, msg,
subject := msg name
if(subject == "") then(
/* it is empty. that means that's an expression inside parens */
expr := ("(" .. msg arguments map(arg, parseMessage(table, arg)) join(" ") .. ")") asMutable
n := msg next
while(n isNil not,
expr appendSeq(parseMessage(table, n))
n = n next
)
return(expr)
) elseif(OperatorTable operators hasKey(subject)) then(
/* do an Io operator -> SQL operator conversion */
ret := subject switch(
"==",
" = #{ parseMessage(table, msg argAt(0)) }" interpolate,
"and",
" AND (#{ parseMessage(table, msg argAt(0)) })" interpolate
"or",
" OR (#{ parseMessage(table, msg argAt(0)) })" interpolate
)
if(ret isNil,
ConditionError raise("Unwrapped operator: #{ subject }" interpolate)
)
return(ret)
) elseif(table hasField(subject) not) then(
/* is an Io object. subsitute. */
expr := table session quote(onlyMessage(msg) doInContext(call sender) asSimpleString asSymbol) asMutable
n := msg next
while(n isNil not,
expr appendSeq(parseMessage(table, n))
n = n next
)
return(expr)
) else(
/* is a table field. keep (That is NOT quoted). */
expr := onlyMessage(msg) asSimpleString asMutable
n := msg next
while(n isNil not,
expr appendSeq(parseMessage(table, n))
n = n next
)
return(expr)
parseSimpleCondition := method(msg, context,
if(context isNil,
context = thisContext
)
one := msg clone setNext(nil) asString
field := Iorm Condition Field with(one)
op := msg next name
two := msg next argAt(0) doInContext(context)
value := Iorm Condition Value with(two)
node := op switch(
"==",
Iorm Condition Equals with(field, value),
"!=",
Iorm Condition Differs with(field, value),
">",
Iorm Condition GreaterThan with(field, value),
"<",
Iorm Condition LessThan with(field, value)
)
if(node isNil,
ConditionError raise("No appropriate SQL operator found for '#{ op }'" interpolate)
)
node
)

parseCondition := method(table,
parseMessage(table, call message argAt(1))
parseSimple := method(
msg := call message argAt(0)
context := call message argAt(1) ifNilEval(thisContext)
parseSimpleCondition(msg, context)
)

Condition := Object clone do(
expression := nil
table ::= nil
children ::= nil

init := method(
children = list()
resend
)

getAsSQL := method(session,
Iorm parseMessage(table, expression)
children map(getAsSQL(session)) join(" AND ") # right?
)

addChild := method(child,
children append(child)
self
)

addFilterCondition := method(condition,
addChild(condition) # if we use AND to join the conditions, that's ok
self
)

setExpression := method(
expression = call message argAt(0)
filter := method(
# for the lazy ones
addFilterCondition(Iorm parseSimpleCondition(call message argAt(0)))
self
)

with := method(
c := self clone
c expression = call message argAt(0)
call evalArgs foreach(child, c addChild(child))
c
)

Value := clone do(
value ::= nil

getAsSQL := method(session,
session quote(value asString asSymbol)
)

with := method(value,
c := self clone
c setValue(value)
c
)
)

Field := clone do(
name ::= nil

getAsSQL := method(session,
name
)

with := method(name,
c := self clone
c setName(name)
c
)
)

BinaryOperator := clone do(
operator ::= nil

getAsSQL := method(session,
children map(getAsSQL(session)) join(" #{ operator } " interpolate)
)
)

Equals := BinaryOperator clone setOperator("=")
Differs := BinaryOperator clone setOperator("!=")
GreaterThan := BinaryOperator clone setOperator(">")
LessThan := BinaryOperator clone setOperator("<")
And := BinaryOperator clone setOperator("AND")
)

6 changes: 4 additions & 2 deletions iorm/Mapper.io
Expand Up @@ -39,9 +39,11 @@ Model := Object clone do(
session executeNow(insert)
)
/* now do the UPDATE query */
query := Iorm Update clone setTable(table) setFields(fields) setCondition(
Iorm Condition clone setExpression(primaryKey == "a")
update := Iorm Update clone setTable(table) setFields(fields) setCondition(
pk := (Message clone fromString(primaryKey))
Iorm Condition with(pk == "foo")
)
session executeNow(update)
)
)
)
Expand Down
1 change: 1 addition & 0 deletions iorm/Query.io
Expand Up @@ -72,6 +72,7 @@ Update := Object clone do(
) join(", "))
query appendSeq(condition getAsSQL)
query appendSeq(";")
query println
query
)

Expand Down
40 changes: 22 additions & 18 deletions test.io
@@ -1,22 +1,26 @@
doRelativeFile("iorm/Iorm.io")

session := Iorm Session withSQLite("./test.sqlite")
#
#Foo := Iorm Model clone do(
# setTableName("Foo")
# newField("integer", Iorm IntegerField clone)
# newField("string", Iorm VarcharField clone setLength(50))
## setPrimaryKey("integer")
#) setSession(session)

Foo := Iorm Model clone do(
setTableName("Foo")
newField("integer", Iorm IntegerField clone)
newField("string", Iorm VarcharField clone setLength(50))
setPrimaryKey("integer")
) setSession(session)

Foo done create

foo := Foo clone setInteger(123) setString("Hello World!") save

cond := Iorm Condition with(integer == 123)
qry := Iorm Select clone setTable(Foo table) setCondition(cond)

session query(qry) foreach(rec,
rec at("integer") println
rec at("string") println
)
foo := "abc"
cond := Iorm Condition clone filter(FIELD1 != "acb") filter(FIELD2 == foo)
cond getAsSQL(session) println
#filter(a == foo)
#Foo done create
#
#foo := Foo clone setInteger(123) setString("Hello World!") save
##
#cond := Iorm Condition with(integer == 123)
#qry := Iorm Select clone setTable(Foo table) setCondition(cond)
#
#session query(qry) foreach(rec,
# rec at("integer") println
# rec at("string") println
#)

0 comments on commit 59aa4a2

Please sign in to comment.