[Lift] **BREAKING CHANGES** in lift-record

2010-03-04 Thread Ross Mellgren
As I mentioned before, I was planning to make some breaking changes to 
lift-record, and since I got no additional feedback, I've now pushed to master.

These changes make some cleanups to method naming and functionality in 
lift-record, and all code using 2.0-SNAPSHOT will need some changes:

 - Each MetaRecord implementation must define createRecord. To migrate, add 
this method to your MetaRecord:
 def createRecord: MyRecord = new MyRecord

 - If you previously used Record#fromJSON, you will need to use 
Record#setFieldsFromJSON instead.
 - If you previously used MetaRecord#createRecord(json: String), you will need 
to use MetaRecord#fromJSON instead.
 - If you previously used MetaRecord#fromJSON(inst, json), you will need to use 
MetaRecord#setFieldsFromJSON instead.

In addition, lift-couchdb has been updated to track these changes:

 - If you previously used JSONRecord#fromJValue, you will need to use 
JSONRecord#setFieldsFromJValue instead.
 - If you previously used JSONMetaRecord#fromJValue(rec, jvalue), you will need 
to use JSONMetaRecord#setFieldsFromJValue instead.
 - CouchMetaRecord#create and CouchMetaRecord#createFromJValue have been 
removed. Use MetaRecord#createRecord and JSONMetaRecord#fromJValue instead.

Let me know if anyone has any problems.

-Ross

On Feb 27, 2010, at 11:53 AM, Ross Mellgren wrote:

> Hey all,
> 
> So as a result of an infelicity in the way records are initialized that 
> tripped up Tim a week or two ago, I'm planning on doing some cleanup to 
> lift-record. It is a breaking change, and it was noted that it'd be good to 
> get opinions on this, so here we are!
> 
> The original problem was that if you used "new MyRecord" then you'd get a 
> record that was basically functional but some of the extended metadata 
> (notably field.name) would not be initialized correctly. This is because the 
> correct way to create a record was MyRecordMeta.createRecord.
> 
> I fixed it so that new MyRecord is equivalent to MyRecordMeta.createRecord, 
> but Marius pointed out there was more cleaning to do.
> 
> Here are the changes:
> - I made the createRecord method on MetaRecord abstract, so that MyRecordMeta 
> must now implement it. If you are porting over old code, then just do:
> def createRecord = new MyRecord
>   This change is so that record creation must be explicitly specified in case 
> it is different from new MyRecord (the default implementation)
> 
> - MetaRecord.fromJSON(inst, json) has been renamed to setFieldsFromJSON(inst, 
> json)
> - a new method MetaRecord.setFieldsFromReq(inst, req) has been created to 
> parallel the new name of fromJSON
> - MetaRecord.createRecord(json) has been renamed to fromJSON(json)
> - Record.fromJSON has been renamed to setFieldsFromJSON
> - Record.setFieldsFromReq has been added -- they just call the meta methods 
> of the same name.
> 
> These changes at the end make it so that fromSomething(something) are 
> consistently factory methods that create records from some source (JSON or 
> Req), and that setFieldsFromSomething(inst, something) is consistently there 
> for setting the fields from the source.
> 
> Let me know what you think.
> 
> -Ross
> 
> 

-- 
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.



[Lift] Breaking changes in lift-record 2.0-SNAPSHOT - Optional fields

2010-02-11 Thread Ross Mellgren
I just committed a change to lift-record in 2.0-SNAPSHOT that will possibly 
(probably?) break your build if you use it.

This change makes it possible to have any record field be optional -- that is, 
Box[MyType]. You use it like this:

object MyRecord extends Record[MyRecord] {
object myNormalField extends StringField(this, 100)
object myOptionalField extends StringField(this, 100) {
override def optional_? = true
override def defaultValueBox = Empty
override def defaultValue = "nothin"
}
}

val r: MyRecord

r.myNormalField.set("Hello") // as before the change
r.myOptionalField.setBox(Empty)

r.myNormalField.value == "Hello" // as before
r.myNormalField.valueBox == Full("Hello")
r.myOptionalField.valueBox == Empty
r.myOptionalField.value == "nothin" // because defaultValue was used to give 
back something

As part of this change, the semantics for field errors has changed somewhat -- 
hopefully, to be more consistent.

Previously if you tried to set a field and checkCanWrite_? returned false then 
an internal flag "valueCouldNotBeSet" on the field will be raised which makes 
that field generate a validation error when validate is called on the record. 
In addition, some fields (but not all) would raise the same flag and return 
Failure or Empty from setFromString or setFromAny upon being given an invalid 
value.

With this change, all types of failure to set now result in the field value 
becoming a Failure. setFromAny, setFromString, and setBox all return that 
Failure, while set will return defaultValue (due to its return type.)

validators and set filters have had their types changed to Boxed equivalents.

And finally, I made consistent the setFromAny methods of all the built-in field 
types so that they all follow the same contract. For setFromAny it's 
essentially accept one of MyType, Box[MyType], Option[MyType], or List[MyType] 
as well as null, with a default to convert an unknown input to string and use 
setFromString. For setFromString, it is as before, except if the field is 
optional_? and the empty string is passed in, that's treated as Empty.

As I'll mention in another message, I also pushed lift-couchdb to master. I ran 
the unit tests that I wrote for that, but that doesn't give me full confidence 
that all the fields are entirely bug free. Similarly I did not test the form 
generation. If anybody runs into any issues please let me know and I'll fix it 
as soon as I can. And of course if it causes too much breakage we can revert it 
back out.

-Ross


-- 
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to lift...@googlegroups.com.
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en.