killbill-uncached

Remove unique constraints for custom_fields on fields (object_id,

1/15/2014 10:36:40 PM

Details

diff --git a/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java b/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java
index 9bf7039..6abe1e3 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/api/DefaultCustomFieldUserApi.java
@@ -16,9 +16,13 @@
 
 package com.ning.billing.util.customfield.api;
 
+import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
+import com.ning.billing.ErrorCode;
 import com.ning.billing.ObjectType;
 import com.ning.billing.util.api.CustomFieldApiException;
 import com.ning.billing.util.api.CustomFieldUserApi;
@@ -33,6 +37,7 @@ import com.ning.billing.util.customfield.dao.CustomFieldModelDao;
 import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
 import com.google.inject.Inject;
 
 public class DefaultCustomFieldUserApi implements CustomFieldUserApi {
@@ -49,7 +54,35 @@ public class DefaultCustomFieldUserApi implements CustomFieldUserApi {
     @Override
     public void addCustomFields(final List<CustomField> customFields, final CallContext context) throws CustomFieldApiException {
         // TODO make it transactional
+
+        final Map<UUID, ObjectType> mapping = new HashMap<UUID, ObjectType>();
+        for (final CustomField cur : customFields) {
+            mapping.put(cur.getObjectId(), cur.getObjectType());
+        }
+
+        final List<CustomFieldModelDao> all = new LinkedList<CustomFieldModelDao>();
+        for (UUID cur : mapping.keySet()) {
+            final ObjectType type = mapping.get(cur);
+            all.addAll(customFieldDao.getCustomFieldsForObject(cur, type, internalCallContextFactory.createInternalCallContext(cur, type, context)));
+        }
+        final List<CustomField> toBeInserted = new LinkedList<CustomField>();
         for (final CustomField cur : customFields) {
+            final CustomFieldModelDao match = Iterables.tryFind(all, new com.google.common.base.Predicate<CustomFieldModelDao>() {
+                @Override
+                public boolean apply(final CustomFieldModelDao input) {
+                    return input.getObjectId().equals(cur.getObjectId()) &&
+                           input.getObjectType() == cur.getObjectType() &&
+                           input.getFieldName().equals(cur.getFieldName());
+
+                }
+            }).orNull();
+            if (match != null) {
+                throw new CustomFieldApiException(ErrorCode.CUSTOM_FIELD_ALREADY_EXISTS, match.getId());
+            }
+            toBeInserted.add(cur);
+        }
+
+        for (CustomField cur : toBeInserted) {
             customFieldDao.create(new CustomFieldModelDao(cur), internalCallContextFactory.createInternalCallContext(cur.getObjectId(), cur.getObjectType(), context));
         }
     }
diff --git a/util/src/main/resources/com/ning/billing/util/ddl.sql b/util/src/main/resources/com/ning/billing/util/ddl.sql
index 6fcbf12..b52df6f 100644
--- a/util/src/main/resources/com/ning/billing/util/ddl.sql
+++ b/util/src/main/resources/com/ning/billing/util/ddl.sql
@@ -19,7 +19,6 @@ CREATE TABLE custom_fields (
 ) CHARACTER SET utf8 COLLATE utf8_bin;
 CREATE UNIQUE INDEX custom_fields_id ON custom_fields(id);
 CREATE INDEX custom_fields_object_id_object_type ON custom_fields(object_id, object_type);
-CREATE UNIQUE INDEX custom_fields_unique ON custom_fields(object_id, object_type, field_name);
 CREATE INDEX custom_fields_tenant_account_record_id ON custom_fields(tenant_record_id, account_record_id);
 
 DROP TABLE IF EXISTS custom_field_history;
diff --git a/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java b/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
index 5465917..d7c449c 100644
--- a/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
+++ b/util/src/test/java/com/ning/billing/util/customfield/api/TestDefaultCustomFieldUserApi.java
@@ -52,7 +52,9 @@ public class TestDefaultCustomFieldUserApi extends UtilTestSuiteWithEmbeddedDB {
             }
         });
 
-        final CustomField customField = new StringCustomField(UUID.randomUUID().toString().substring(1, 4), UUID.randomUUID().toString().substring(1, 4), ObjectType.ACCOUNT, accountId, callContext.getCreatedDate());
+        final String cfName = UUID.randomUUID().toString().substring(1, 4);
+        final String cfValue = UUID.randomUUID().toString().substring(1, 4);
+        final CustomField customField = new StringCustomField(cfName, cfValue, ObjectType.ACCOUNT, accountId, callContext.getCreatedDate());
         eventsListener.pushExpectedEvent(NextEvent.CUSTOM_FIELD);
         customFieldUserApi.addCustomFields(ImmutableList.<CustomField>of(customField), callContext);
         assertListenerStatus();
@@ -74,7 +76,21 @@ public class TestDefaultCustomFieldUserApi extends UtilTestSuiteWithEmbeddedDB {
         });
 
         customFieldUserApi.removeCustomFields(customFields, callContext);
-        final List<CustomField> remainingCustomFields = customFieldUserApi.getCustomFieldsForObject(accountId, ObjectType.ACCOUNT, callContext);
+        List<CustomField> remainingCustomFields = customFieldUserApi.getCustomFieldsForObject(accountId, ObjectType.ACCOUNT, callContext);
         Assert.assertEquals(remainingCustomFields.size(), 0);
+
+        // Add again the custom field
+        final CustomField newCustomField = new StringCustomField(cfName, cfValue, ObjectType.ACCOUNT, accountId, callContext.getCreatedDate());
+
+        eventsListener.pushExpectedEvent(NextEvent.CUSTOM_FIELD);
+        customFieldUserApi.addCustomFields(ImmutableList.<CustomField>of(newCustomField), callContext);
+        remainingCustomFields = customFieldUserApi.getCustomFieldsForObject(accountId, ObjectType.ACCOUNT, callContext);
+        Assert.assertEquals(remainingCustomFields.size(), 1);
+
+        // Delete again
+        customFieldUserApi.removeCustomFields(remainingCustomFields, callContext);
+        remainingCustomFields = customFieldUserApi.getCustomFieldsForObject(accountId, ObjectType.ACCOUNT, callContext);
+        Assert.assertEquals(remainingCustomFields.size(), 0);
+
     }
 }