Skip to content

Commit 0c5ef2f

Browse files
committed
Fixed Column Order for Insert. Insert String constructed in 1 loop.
1 parent ce4290d commit 0c5ef2f

File tree

6 files changed

+54
-33
lines changed

6 files changed

+54
-33
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>io.github.sproket</groupId>
88
<artifactId>persism</artifactId>
9-
<version>1.1.0b</version>
9+
<version>1.1.0</version>
1010
<packaging>jar</packaging>
1111

1212
<build>

release-notes.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
## Release Notes
22

3+
### 1.1.0
4+
5+
* Added support for Records! (Java 16)
6+
* Added preliminary support for Informix (looking for help to set up a vbox vm)
7+
* Fixed UPDATE statement using columns in alphabetical order (All Persism generated SQL should be in column order)
8+
* Fixed support for MSAccess with UCanAccess jdbc driver in Java 16
9+
* Fixed issue with Queries cached with missing columns
10+
* Fixed @Table name case sensitivity
11+
* Added warnings if Persism doesn't have results when querying for DatabaseMetaData
12+
13+
### Breaking changes
14+
15+
* Insert now returns a typed Result object containing the rows changed and modified data object for cases when you insert a Record and there are defaults or autoincs to assign.
16+
317
### 1.0.3
418

519
* Added support for MSAccess with UCanAccess jdbc driver (seems to be broken under Java 16 right now #13)

src/net/sf/persism/MetaData.java

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.lang.reflect.Method;
1111
import java.lang.reflect.Modifier;
1212
import java.sql.*;
13+
import java.text.MessageFormat;
1314
import java.util.*;
1415
import java.util.concurrent.ConcurrentHashMap;
1516

@@ -107,7 +108,7 @@ private synchronized <T> Map<String, PropertyInfo> determinePropertyInfo(Class<T
107108
try {
108109
st = connection.createStatement();
109110
// gives us real column names with case.
110-
String sql = new StringBuilder().append("SELECT * FROM ").append(sd).append(tableName).append(ed).append(" WHERE 1=0").toString();
111+
String sql = MessageFormat.format("SELECT * FROM {0}{1}{2} WHERE 1=0", sd, tableName, ed); // todo this is repeated - put the string in a static final
111112
if (log.isDebugEnabled()) {
112113
log.debug("determineColumns: %s", sql);
113114
}
@@ -132,7 +133,8 @@ private synchronized <T> Map<String, PropertyInfo> determinePropertyInfo(Class<T
132133
Collection<PropertyInfo> properties = getPropertyInfo(objectClass);
133134

134135
int columnCount = rsmd.getColumnCount();
135-
Map<String, PropertyInfo> columns = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
136+
//Map<String, PropertyInfo> columns = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
137+
Map<String, PropertyInfo> columns = new LinkedHashMap<>(columnCount);
136138
for (int j = 1; j <= columnCount; j++) {
137139
String realColumnName = rsmd.getColumnLabel(j);
138140
String columnName = realColumnName.toLowerCase().replace("_", "").replace(" ", "");
@@ -382,9 +384,9 @@ private static synchronized <T> Collection<PropertyInfo> determinePropertyInfo(C
382384
if (Modifier.isStatic(field.getModifiers())) {
383385
continue;
384386
}
385-
log.debug("Field Name: %s", field.getName());
387+
// log.debug("Field Name: %s", field.getName());
386388
String propertyName = field.getName();
387-
log.debug("Property Name: *%s* ", propertyName);
389+
// log.debug("Property Name: *%s* ", propertyName);
388390

389391
PropertyInfo propertyInfo = new PropertyInfo();
390392
propertyInfo.propertyName = propertyName;
@@ -396,15 +398,15 @@ private static synchronized <T> Collection<PropertyInfo> determinePropertyInfo(C
396398

397399
for (Method method : methods) {
398400
String propertyNameToTest = field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
399-
log.debug("property name for testing %s", propertyNameToTest);
401+
// log.debug("property name for testing %s", propertyNameToTest);
400402
if (propertyNameToTest.startsWith("Is") && propertyNameToTest.length() > 2 && Character.isUpperCase(propertyNameToTest.charAt(2))) {
401403
propertyNameToTest = propertyName.substring(2);
402404
}
403405

404406
String[] candidates = {"set" + propertyNameToTest, "get" + propertyNameToTest, "is" + propertyNameToTest, field.getName()};
405407

406408
if (Arrays.asList(candidates).contains(method.getName())) {
407-
log.debug(" METHOD: %s", method.getName());
409+
//log.debug(" METHOD: %s", method.getName());
408410

409411
annotations = method.getAnnotations();
410412
for (Annotation annotation : annotations) {
@@ -476,7 +478,7 @@ private void populateTableList(Connection con) throws PersismException {
476478
String getUpdateStatement(Object object, Connection connection) throws PersismException, NoChangesDetectedForUpdateException {
477479

478480
if (object instanceof Persistable) {
479-
Map<String, PropertyInfo> changes = getChangedProperties((Persistable) object, connection);
481+
Map<String, PropertyInfo> changes = getChangedProperties((Persistable<?>) object, connection);
480482
if (changes.size() == 0) {
481483
throw new NoChangesDetectedForUpdateException();
482484
}
@@ -549,8 +551,13 @@ private synchronized String determineInsertStatement(Object object, Connection c
549551

550552
Map<String, ColumnInfo> columns = getColumns(object.getClass(), connection);
551553
Map<String, PropertyInfo> properties = getTableColumnsPropertyInfo(object.getClass(), connection);
552-
StringBuilder sb = new StringBuilder();
553-
sb.append("INSERT INTO ").append(sd).append(tableName).append(ed).append(" (");
554+
555+
StringBuilder sbi = new StringBuilder();
556+
sbi.append("INSERT INTO ").append(sd).append(tableName).append(ed).append(" (");
557+
558+
StringBuilder sbp = new StringBuilder();
559+
sbp.append(") VALUES (");
560+
554561
String sep = "";
555562
boolean saveInMap = true;
556563

@@ -568,31 +575,17 @@ private synchronized String determineInsertStatement(Object object, Connection c
568575
}
569576

570577
}
571-
sb.append(sep).append(sd).append(column.columnName).append(ed);
572-
sep = ", ";
573-
}
574-
}
575-
sb.append(") VALUES (");
576-
sep = "";
577-
for (ColumnInfo column : columns.values()) {
578-
if (!column.autoIncrement) {
579578

580-
if (column.hasDefault) {
581-
// Do not include if this column has a default and no value has been
582-
// set on it's associated property.
583-
if (properties.get(column.columnName).getter.invoke(object) == null) {
584-
continue;
585-
}
586-
}
587-
588-
sb.append(sep).append(" ? ");
579+
sbi.append(sep).append(sd).append(column.columnName).append(ed);
580+
sbp.append(sep).append("?");
589581
sep = ", ";
590582
}
591583
}
592-
sb.append(") ");
584+
585+
sbi.append(sbp).append(") ");
593586

594587
String insertStatement;
595-
insertStatement = sb.toString();
588+
insertStatement = sbi.toString();
596589

597590
if (log.isDebugEnabled()) {
598591
log.debug("determineInsertStatement for %s is %s", object.getClass(), insertStatement);
@@ -733,10 +726,10 @@ private String buildUpdateString(Object object, Iterator<String> it, Connection
733726
return sb.toString();
734727
}
735728

736-
Map<String, PropertyInfo> getChangedProperties(Persistable persistable, Connection connection) throws PersismException {
729+
Map<String, PropertyInfo> getChangedProperties(Persistable<?> persistable, Connection connection) throws PersismException {
737730

738731
try {
739-
Persistable original = (Persistable) persistable.readOriginalValue();
732+
Persistable<?> original = (Persistable<?>) persistable.readOriginalValue();
740733

741734
Map<String, PropertyInfo> columns = getTableColumnsPropertyInfo(persistable.getClass(), connection);
742735

src/net/sf/persism/Reader.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ <T> T readObject(Object object, ResultSet rs) throws IllegalAccessException, SQL
6868
for (int j = 1; j <= columnCount; j++) {
6969

7070
String columnName = rsmd.getColumnLabel(j);
71-
PropertyInfo columnProperty = properties.get(columnName);
71+
PropertyInfo columnProperty = getPropertyInfo(columnName, properties); //properties.get(columnName);
7272

7373
if (columnProperty != null) {
7474
Class<?> returnType = columnProperty.getter.getReturnType();
@@ -388,4 +388,15 @@ <T> T readColumn(ResultSet rs, int column, Class<?> returnType) throws SQLExcept
388388

389389
return (T) value;
390390
}
391+
392+
// Poor man's case insensitive linked hash map ;)
393+
private PropertyInfo getPropertyInfo(String col, Map<String, PropertyInfo> properties) {
394+
for (String key : properties.keySet()) {
395+
if (key.equalsIgnoreCase(col)) {
396+
return properties.get(key);
397+
}
398+
}
399+
return null;
400+
}
401+
391402
}

test/mssql.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# datasource properties used in junit test and development
22
# Note -Djsse.enableCBCProtection=false needed as java runtime param to make SQL connections work.
3-
database.url=jdbc:sqlserver://pinf-win;databaseName=PINF
3+
#database.url=jdbc:sqlserver://pinf-win;databaseName=PINF
4+
database.url=jdbc:sqlserver://localhost;databaseName=PINF
45
#database.url=jdbc:sqlserver://192.168.1.116;databaseName=PINF
56
database.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
67
database.username=pinf

test/net/sf/persism/BaseTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,9 @@ public void testContactTable() throws SQLException {
464464
Contact contactForTest = getContactForTest();
465465
contactForTest.setIdentity(randomUUID);
466466
session.insert(contactForTest);
467+
contactForTest.setAddress1("123 Somewhere");
467468
contactForTest.setContactName("HELLO?!");
469+
contactForTest.setNotes("notes?");
468470
session.update(contactForTest);
469471
session.fetch(contactForTest);
470472

0 commit comments

Comments
 (0)