diff --git a/iorm/Condition.io b/iorm/Condition.io index afa2131..e0915bb 100644 --- a/iorm/Condition.io +++ b/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") ) diff --git a/iorm/Mapper.io b/iorm/Mapper.io index 0581bb8..7e3f94b 100644 --- a/iorm/Mapper.io +++ b/iorm/Mapper.io @@ -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) ) ) ) diff --git a/iorm/Query.io b/iorm/Query.io index 8cc293d..1d551c9 100644 --- a/iorm/Query.io +++ b/iorm/Query.io @@ -72,6 +72,7 @@ Update := Object clone do( ) join(", ")) query appendSeq(condition getAsSQL) query appendSeq(";") + query println query ) diff --git a/test.io b/test.io index 0c4cac3..f1aec9f 100644 --- a/test.io +++ b/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 +#)