Commit 9ae5aa24 by Juho Juopperi

Initial commit of the metadata feature.

1 parent b55e8ba0
...@@ -22,6 +22,20 @@ public class BootstrapBean implements BootstrapBeanLocal { ...@@ -22,6 +22,20 @@ public class BootstrapBean implements BootstrapBeanLocal {
public BootstrapBean() { public BootstrapBean() {
} }
/**
* Runs a "ALTER TABLE <table> <statement>" for each of tables.
* @param alterStatement e.g. "ADD meta json"
* @param tables table name strings
* @return1
*/
private static final String[] alterTables(String alterStatement, String... tables) {
String[] strings = new String[tables.length];
for (int i=0; i<tables.length; i++) {
strings[i] = "ALTER TABLE \""+ tables[i] + "\" " + alterStatement;
}
return strings;
}
private static final List<String[]> dbUpdates = new ArrayList<String[]>(); private static final List<String[]> dbUpdates = new ArrayList<String[]>();
static { static {
...@@ -60,7 +74,7 @@ public class BootstrapBean implements BootstrapBeanLocal { ...@@ -60,7 +74,7 @@ public class BootstrapBean implements BootstrapBeanLocal {
dbUpdates.add(new String[] { dbUpdates.add(new String[] {
"alter table compos add hidden boolean default false not null" "alter table compos add hidden boolean default false not null"
}); });
dbUpdates.add(alterTables("ADD COLUMN meta json", "account_events", "actionlog_messages", "actionlog_message_responses", "application_permissions", "approvals", "bills", "bill_lines", "card_barcode", "card_templates", "compos", "compo_entries", "compo_entry_files", "compo_entry_participations", "db_models", "discounts", "discount_instances"));
} }
@EJB @EJB
......
...@@ -57,5 +57,10 @@ ...@@ -57,5 +57,10 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.3-1100-jdbc41</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
...@@ -15,6 +15,7 @@ public class MoyaPostgreSQLPlatform extends PostgreSQLPlatform { ...@@ -15,6 +15,7 @@ public class MoyaPostgreSQLPlatform extends PostgreSQLPlatform {
map.put(String.class, new FieldTypeDefinition("TEXT", false)); map.put(String.class, new FieldTypeDefinition("TEXT", false));
map.put(java.sql.Timestamp.class, new FieldTypeDefinition("TIMESTAMPTZ", false)); map.put(java.sql.Timestamp.class, new FieldTypeDefinition("TIMESTAMPTZ", false));
map.put(javax.json.JsonObject.class, new FieldTypeDefinition("JSON", false));
return map; return map;
} }
......
package fi.codecrew.moya.model;
import javax.json.JsonObject;
/**
* Entities that have a JSON meta data column implement this interface.
*
* Meta data can be just about anything that is not deemed to be essential
* enough to have it's own column. Including people's shirt sizes etc.
*
* @author jkj
*/
public interface EntityMeta {
/**
* Get JSON metadata associated with the entity.
*
* @return JsonObject from meta column in DB.
*/
public JsonObject getMeta();
/**
* Associate JSON metadata to entity.
*
* @param meta
* JsonObject that goes into meta column in DB.
*/
public void setMeta(JsonObject meta);
}
package fi.codecrew.moya.model; package fi.codecrew.moya.model;
import javax.json.JsonObject;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
...@@ -10,7 +11,7 @@ import fi.codecrew.moya.utilities.jpa.EntityEquals; ...@@ -10,7 +11,7 @@ import fi.codecrew.moya.utilities.jpa.EntityEquals;
import fi.codecrew.moya.utilities.jpa.ModelInterface; import fi.codecrew.moya.utilities.jpa.ModelInterface;
@MappedSuperclass @MappedSuperclass
public class GenericEntity extends EntityEquals implements ModelInterface { public class GenericEntity extends EntityEquals implements ModelInterface, EntityMeta {
private static final long serialVersionUID = -9041737052951021560L; private static final long serialVersionUID = -9041737052951021560L;
public static final String ID_COLUMN = "id"; public static final String ID_COLUMN = "id";
...@@ -20,6 +21,8 @@ public class GenericEntity extends EntityEquals implements ModelInterface { ...@@ -20,6 +21,8 @@ public class GenericEntity extends EntityEquals implements ModelInterface {
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; private Integer id;
private JsonObject meta;
@Override @Override
public final Integer getId() { public final Integer getId() {
return id; return id;
...@@ -30,4 +33,14 @@ public class GenericEntity extends EntityEquals implements ModelInterface { ...@@ -30,4 +33,14 @@ public class GenericEntity extends EntityEquals implements ModelInterface {
this.id = id; this.id = id;
} }
@Override
public JsonObject getMeta() {
return meta;
}
@Override
public void setMeta(JsonObject meta) {
this.meta = meta;
}
} }
package fi.codecrew.moya.model.converters;
import java.io.StringReader;
import java.sql.SQLException;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import org.postgresql.util.PGobject;
@Converter(autoApply = true)
public class JsonAttributeConverter implements AttributeConverter<JsonObject, PGobject> {
public PGobject convertToDatabaseColumn(JsonObject attribute) {
if (attribute == null) {
return null;
}
final PGobject dataValue = new PGobject();
dataValue.setType("json");
try {
dataValue.setValue(attribute.toString());
} catch (SQLException e) {
// This will never run because PGobject.setValue() cannot really
// throw an SQLException. There is nothing but setting a property.
throw new RuntimeException("THIS SHOULD NEVER HAPPEN", e);
}
return dataValue;
}
public JsonObject convertToEntityAttribute(PGobject dbData) {
// Has any?
if (dbData == null) {
return null;
}
// Correct type of object?
if (dbData.getType().equals("json") == false) {
throw new RuntimeException("Expected JSON object from database");
}
// Read as JSON object
final StringReader stringReader = new StringReader(dbData.getValue());
final JsonReader jsonReader = Json.createReader(stringReader);
return jsonReader.readObject();
}
}
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
<dependent-module archiveName="org.ancoron.postgresql.jpa-9.1.901.jdbc4.1-rc9.jar" deploy-path="/lib" handle="module:/classpath/var/M2_REPO/org/ancoron/postgresql/org.ancoron.postgresql.jpa/9.1.901.jdbc4.1-rc9/org.ancoron.postgresql.jpa-9.1.901.jdbc4.1-rc9.jar"> <dependent-module archiveName="org.ancoron.postgresql.jpa-9.1.901.jdbc4.1-rc9.jar" deploy-path="/lib" handle="module:/classpath/var/M2_REPO/org/ancoron/postgresql/org.ancoron.postgresql.jpa/9.1.901.jdbc4.1-rc9/org.ancoron.postgresql.jpa-9.1.901.jdbc4.1-rc9.jar">
<dependency-type>uses</dependency-type> <dependency-type>uses</dependency-type>
</dependent-module> </dependent-module>
<dependent-module archiveName="postgresql-9.3-1100-jdbc41.jar" deploy-path="/lib" handle="module:/classpath/var/M2_REPO/org/postgresql/postgresql/9.3-1100-jdbc41/postgresql-9.3-1100-jdbc41.jar">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module archiveName="pdfjet-0.0.0-2013-08-19.jar" deploy-path="/lib" handle="module:/classpath/var/M2_REPO/fi/iudex/pdfjet/pdfjet/0.0.0-2013-08-19/pdfjet-0.0.0-2013-08-19.jar"> <dependent-module archiveName="pdfjet-0.0.0-2013-08-19.jar" deploy-path="/lib" handle="module:/classpath/var/M2_REPO/fi/iudex/pdfjet/pdfjet/0.0.0-2013-08-19/pdfjet-0.0.0-2013-08-19.jar">
<dependency-type>uses</dependency-type> <dependency-type>uses</dependency-type>
</dependent-module> </dependent-module>
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!