I have a proposed change to XWikiHibernateStore#saveXWikiProperty which will 
make this migration possible.
The change makes it so that when one saves a property which has the same name 
and number as an existing
property, the old property is cleared and replaced rather than causing an 
exception.
This will not only smooth over any problems caused by stray properties which 
were not deleted properly
but will make it much easier to change a property type.

Here's the patch as I propose it (I plan to add a number of tests if there 
isn't disagreement with the change)


Index: src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java
===================================================================
--- src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java  (revision 30732)
+++ src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java  (working copy)
@@ -1416,14 +1416,28 @@
             final Session session = this.getSession(context);

             final Query query = session.createQuery(
-                "select prop.name from BaseProperty as prop where prop.id.id = 
:id and prop.id.name= :name");
+                "select prop.classType from BaseProperty as prop where 
prop.id.id = :id and prop.id.name= :name");
             query.setInteger("id", property.getId());
             query.setString("name", property.getName());

-            if (query.uniqueResult() == null) {
+            final List response = query.list();
+
+            if (response.size() > 0) {
+                if (!property.getClassType().equals(response.get(0))) {
+                    // If we are trying to save a property and there is 
already a property of a different type,
+                    // lets remove it first rather than blowing up with an 
exception.
+                    final BaseProperty toDelete = new BaseProperty();
+                    toDelete.setId(property.getId());
+                    toDelete.setName(property.getName());
+                    session.delete(toDelete);
+                    session.save(property);
+                } else {
+                    // Property already in the database.
+                    session.update(property);
+                }
+            } else {
+                // Property not already in the database.
                 session.save(property);
-            } else {
-                session.update(property);
             }

             if (bTransaction) {



WDYT?

Caleb




Caleb James DeLisle wrote:
> Base64 is a standard way of storing encrypted content. It could be changed to 
> base128 but it would include
> a large number of non printing characters such as backspace. Any base over 
> base128 would be interpreted as
> invalid UTF-8 and cause errors in the database. Also The size of the encoded 
> data is well over the 256
> character limit and doubling the base only cuts off less than 1/3 of the 
> number of characters needed so I
> don't think even base128 would be enough to make the password functions fit 
> in a 255 char string.
> 
> Another option would be to add a binary byte[] property but that would 
> complicate the process even further.
> 
> Caleb
> 
> 
> Marius Dumitru Florea wrote:
>> On 08/10/2010 08:45 PM, Caleb James DeLisle wrote:
>>> Because protectPassword generates a base-64 encoded java serialized form, 
>>> the size is quite a bit larger than
>>> the 255 character limit of StringProperty and thus PasswordProperty.
>> What is the real reason for using base-64 encoding? Why not using a 
>> larger base? You convert the serialized bytes anyway.
>>
>>> The use of java serialization is central to the upgradability of the 
>>> password verification function because
>>> any new class which implements PasswordVerificationFunction automatically 
>>> works.
>> This doesn't explain why you need to store the serialized instance of a 
>> PasswordVerificationFunction implementation as a base-64 string.
>>
>> Thanks,
>> Marius
>>
>>> Given this, I want to migrate the database to move password hashes into the 
>>> xwikilargestrings table and change
>>> PasswordProperty to extend LargeStringProperty. During this migration, any 
>>> passwords still stored in plaintext
>>> will be ported to the scrypt function, passwords stored as a hash will have 
>>> an exclamation mark pretended to the
>>> text (this is invalid base64) and be inserted into the table as is.
>>>
>>> PasswordClass will keep the sha-512 hash function for legacy passwords but 
>>> will port passwords to the new format
>>> as users log in.
>>>
>>> These changes will allow us to close
>>> http://jira.xwiki.org/jira/browse/XWIKI-70
>>> and
>>> http://jira.xwiki.org/jira/browse/XWIKI-582
>>>
>>>
>>> WDYT?
>>>
>>>
>>> Caleb
>>>
>>> _______________________________________________
>>> devs mailing list
>>> [email protected]
>>> http://lists.xwiki.org/mailman/listinfo/devs
>> _______________________________________________
>> devs mailing list
>> [email protected]
>> http://lists.xwiki.org/mailman/listinfo/devs
>>
> 
> _______________________________________________
> devs mailing list
> [email protected]
> http://lists.xwiki.org/mailman/listinfo/devs
> 

_______________________________________________
devs mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/devs

Reply via email to