Skip to content

Commit

Permalink
added support for already existing instances.
Browse files Browse the repository at this point in the history
  • Loading branch information
fredreichbier committed Feb 21, 2009
1 parent 71713ad commit a496095
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
30 changes: 27 additions & 3 deletions iorm/Mapper.io
Expand Up @@ -113,7 +113,24 @@ Model := Object clone do(
return(instance)
)
)
return(nil)
# Not existing -> create
createInstanceFromPrimaryKey(pk)
)

createInstanceFromPrimaryKey := method(pk,
# create and return a new instance of the model
# retrieve all values from the database
condition := Iorm constructTree(table,
Equals(
Field(primaryKey),
Value(pk)
)
)
query := Iorm Select clone setTable(table) setCondition(condition)
inst := self instance
inst setAlreadyExisting(true) # <- important
inst syncFromResult(session query(query))
inst
)

getFieldByName := method(name,
Expand Down Expand Up @@ -146,7 +163,6 @@ Instance := Object clone do(
self newToBeSavedSlot(field name, field value)
self fields append(field clone)
)
setValueOf(model primaryKey, model table generateID)
)

newToBeSavedSlot := method(name, initial,
Expand All @@ -172,13 +188,18 @@ Instance := Object clone do(
)

syncFromResult := method(result,
result first # that's important.
result fields foreach(name,
field := getFieldByName(name)
if(field isNil,
MapperError raise("Unknown field in result: #{ name }" interpolate)
)
# set field's value
field setValueFromSQL(result at(name))
# and the cached value
setValueOf(name, field value)
)
result done # that's also important.
self
)

Expand All @@ -202,6 +223,7 @@ Instance := Object clone do(
if(alreadyExisting not,
/* we have to make INSERT query first */
syncFields
setValueOf(model primaryKey, model table generateID)
insert := Iorm InsertInto clone setTable(model table) setFields(fields)
session executeNow(insert)
alreadyExisting = true
Expand Down Expand Up @@ -240,7 +262,9 @@ Instance := Object clone do(
)

setValueOf := method(name, value,
updateSlot(name, value)
self updateSlot(name, value)
# ... ok. if a field is named `name`, leaving the `self` is not a good idea,
# because the local argument slot will be updated. explicit self, need you.
)

getValueAsSQL := method(
Expand Down
22 changes: 22 additions & 0 deletions samples/existing.io
@@ -0,0 +1,22 @@
# Now we'll see how Iorm operates with existing tables.
doRelativeFile("../iorm/Iorm.io")
# We use the same models as in `basic.io`.
session := Iorm Session withSQLite("./existing.sqlite")

Author := Iorm Model with(session) setup(
setTableName("authors")
newField("name", Iorm VarcharField clone setLength(50))
newField("info", Iorm TextField clone)
)
# No `Author create` ...

Book := Iorm Model with(session) setup(
setTableName("books")
newField("author", Iorm ForeignKeyField with(Author))
newField("title", Iorm VarcharField clone setLength(50))
)
# ... and no `Book create` - they're already existing!

# Now do a query
max_goldt := Author objects filter(name == "Max Goldt") at(0)
max_goldt info println
Binary file added samples/existing.sqlite
Binary file not shown.

0 comments on commit a496095

Please sign in to comment.