Skip to content

Commit

Permalink
fixed errors when initializing Para, using PostgreSQL
Browse files Browse the repository at this point in the history
  • Loading branch information
albogdano committed Jan 20, 2018
1 parent 494dff2 commit 582e9d9
Showing 1 changed file with 68 additions and 36 deletions.
104 changes: 68 additions & 36 deletions src/main/java/com/erudika/para/persistence/SqlUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,10 @@ public final class SqlUtils {

private static final Logger logger = LoggerFactory.getLogger(SqlUtils.class);
private static final String JSON_FIELD_NAME = "json";
private static final String TABLE_SCHEMA = Utils.formatMessage(
"{0} NVARCHAR(64) PRIMARY KEY NOT NULL," +
"{1} NVARCHAR(64) NOT NULL," +
"{2} NVARCHAR(64) DEFAULT NULL," +
"{3} TIMESTAMP NOT NULL," +
"{4} TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP," +
"{5} LONGTEXT NOT NULL",
Config._ID,
Config._TYPE,
Config._CREATORID,
Config._TIMESTAMP,
Config._UPDATED,
JSON_FIELD_NAME
);

private static HikariDataSource hikariDataSource;
private static boolean useMySqlSyntax = false;
private static boolean useMSSqlSyntax = false;
private static boolean usePGSqlSyntax = false;

private SqlUtils() { }

Expand Down Expand Up @@ -97,6 +84,8 @@ static Connection getConnection() throws SQLException {
try {
Class.forName(sqlDriver);
useMySqlSyntax = sqlDriver.contains("mysql");
useMSSqlSyntax = sqlDriver.contains("sqlserver");
usePGSqlSyntax = sqlDriver.contains("postgresql");
} catch (ClassNotFoundException e) {
logger.error("Error loading SQL driver \"" + sqlDriver + "\", class not found.");
return null;
Expand Down Expand Up @@ -143,6 +132,25 @@ protected static void shutdownClient() {
}
}

private static String getTableSchema() {
return Utils.formatMessage(
"{0} {6} PRIMARY KEY NOT NULL,"
+ "{1} {6} NOT NULL,"
+ "{2} {6} DEFAULT NULL,"
+ "{3} TIMESTAMP NOT NULL,"
+ "{4} TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+ "{5} TEXT NOT NULL",
Config._ID,
Config._TYPE,
Config._CREATORID,
Config._TIMESTAMP,
Config._UPDATED,
JSON_FIELD_NAME,
useMSSqlSyntax ? "NVARCHAR(2048)" :
(useMySqlSyntax ? "VARCHAR(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" : "VARCHAR(2048)")
);
}

/**
* Checks if a specific table exists in the SQL database.
* @param appid name of the {@link com.erudika.para.core.App}
Expand Down Expand Up @@ -179,9 +187,10 @@ public static boolean createTable(String appid) {
try (Connection connection = getConnection()) {
String tableName = getTableNameForAppid(appid);
connection.createStatement().execute(Utils.formatMessage(
"CREATE TABLE IF NOT EXISTS {0} ({1})",
"CREATE TABLE IF NOT EXISTS {0} ({1}){2}",
tableName,
TABLE_SCHEMA));
getTableSchema(),
useMySqlSyntax ? " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" : ""));
logger.info("Created SQL database table named '{}'.", tableName);
return true;
} catch (Exception e) {
Expand Down Expand Up @@ -274,16 +283,7 @@ protected static <P extends ParaObject> void createRows(String appid, List<P> ob
}
try (Connection connection = getConnection()) {
String tableName = getTableNameForAppid(appid);
PreparedStatement ps;
if (useMySqlSyntax) {
ps = connection.prepareStatement(Utils.formatMessage(
"INSERT INTO {0} VALUES (?,?,?,?,?,?) ON DUPLICATE KEY UPDATE {1}=?,{2}=?",
tableName,
Config._UPDATED,
JSON_FIELD_NAME));
} else {
ps = connection.prepareStatement("MERGE INTO " + tableName + " VALUES (?,?,?,?,?,?)");
}
PreparedStatement ps = getCreateRowPreparedStatement(connection, tableName);

for (P object : objects) {
if (StringUtils.isBlank(object.getId())) {
Expand All @@ -300,15 +300,22 @@ protected static <P extends ParaObject> void createRows(String appid, List<P> ob
final String objectJson = ParaObjectUtils.getJsonWriterNoIdent().
writeValueAsString(ParaObjectUtils.getAnnotatedFields(object, false));

ps.setString(1, object.getId());
ps.setString(2, object.getType());
ps.setString(3, object.getCreatorid());
ps.setTimestamp(4, createTimestamp);
ps.setTimestamp(5, updateTimestamp);
ps.setString(6, objectJson);
if (useMySqlSyntax) {
ps.setTimestamp(7, updateTimestamp);
ps.setString(8, objectJson);
int positionOffset = 0;
if (useMSSqlSyntax) {
positionOffset = 2;
ps.setTimestamp(1, updateTimestamp);
ps.setString(2, objectJson);
}

ps.setString(positionOffset + 1, object.getId());
ps.setString(positionOffset + 2, object.getType());
ps.setString(positionOffset + 3, object.getCreatorid());
ps.setTimestamp(positionOffset + 4, createTimestamp);
ps.setTimestamp(positionOffset + 5, updateTimestamp);
ps.setString(positionOffset + 6, objectJson);
if (useMySqlSyntax || usePGSqlSyntax) {
ps.setTimestamp(positionOffset + 7, updateTimestamp);
ps.setString(positionOffset + 8, objectJson);
}
ps.addBatch();
}
Expand Down Expand Up @@ -442,6 +449,31 @@ protected static <P extends ParaObject> List<P> readPage(String appid, Pager pag
return Collections.emptyList();
}

private static PreparedStatement getCreateRowPreparedStatement(Connection conn, String tableName) throws SQLException {
PreparedStatement ps;
if (useMySqlSyntax) {
ps = conn.prepareStatement(Utils.formatMessage(
"INSERT INTO {0} VALUES (?,?,?,?,?,?) ON DUPLICATE KEY UPDATE {1}=?,{2}=?",
tableName,
Config._UPDATED,
JSON_FIELD_NAME));
} else if (usePGSqlSyntax) {
ps = conn.prepareStatement(Utils.formatMessage(
"INSERT INTO {0} VALUES (?,?,?,?,?,?) ON CONFLICT ({1}) DO UPDATE SET {2}=?,{3}=?",
tableName,
Config._ID,
Config._UPDATED,
JSON_FIELD_NAME));
} else if (useMSSqlSyntax) {
ps = conn.prepareStatement(Utils.formatMessage("MERGE INTO {0} AS T USING {0} AS S ON T.id = S.id "
+ "WHEN MATCHED THEN UPDATE SET {1}=?,{2}=? WHEN NOT MATCHED THEN INSERT "
+ "VALUES (?,?,?,?,?,?)", tableName, Config._UPDATED, JSON_FIELD_NAME));
} else {
ps = conn.prepareStatement("MERGE INTO " + tableName + " VALUES (?,?,?,?,?,?)");
}
return ps;
}

private static String logSqlError(Exception e) {
if (e == null || !SQLException.class.isAssignableFrom(e.getClass())) {
return "";
Expand Down

0 comments on commit 582e9d9

Please sign in to comment.