diff --git a/.github/badges/branches.svg b/.github/badges/branches.svg index f928b74..d802cbb 100644 --- a/.github/badges/branches.svg +++ b/.github/badges/branches.svg @@ -1 +1 @@ -branches96% \ No newline at end of file +branches90.9% \ No newline at end of file diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg index 4442015..60a61c8 100644 --- a/.github/badges/jacoco.svg +++ b/.github/badges/jacoco.svg @@ -1 +1 @@ -coverage99.6% \ No newline at end of file +coverage98.9% \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 77d855d..0e3598e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,7 +18,7 @@ plugins { } group = "org.viablespark" -version = "1.4.0" +version = "1.5.0" repositories { mavenCentral() @@ -75,7 +75,7 @@ publishing { create("maven") { groupId = "org.viablespark" artifactId = "goodenough-jdbc" - version = "1.4.0" + version = "1.5.0" from(components["java"]) pom { diff --git a/src/main/java/org/viablespark/persistence/BaseRepository.java b/src/main/java/org/viablespark/persistence/BaseRepository.java index dd862c3..a1ff1e8 100644 --- a/src/main/java/org/viablespark/persistence/BaseRepository.java +++ b/src/main/java/org/viablespark/persistence/BaseRepository.java @@ -42,11 +42,11 @@ public Optional save(E entity) throws SQLException { String sql = "INSERT INTO " + deriveEntityName(entity.getClass()) + " " + withInsert.getClause(); KeyHolder key = execWithKey(sql, withInsert.getValues()); if ( key.getKeys() != null ) { - entity.setKey(Key.of(entity.getClass() + entity.setRefs(Key.of(entity.getClass() .getAnnotation(PrimaryKey.class) .value(), key.getKey().longValue())); } - return Optional.ofNullable(entity.getKey()); + return Optional.ofNullable(entity.getRefs()); } SqlClause withUpdate = WithSql.getSQLUpdateClause(entity); @@ -54,14 +54,14 @@ public Optional save(E entity) throws SQLException { + withUpdate.getClause(); jdbc.update(sql, withUpdate.getValues()); - return Optional.ofNullable(entity.getKey()); + return Optional.ofNullable(entity.getRefs()); } public void delete(E entity) { String sql = "DELETE FROM " + deriveEntityName(entity.getClass()) - + " WHERE " + entity.getKey().primaryKey().getKey() + "=? "; + + " WHERE " + entity.getRefs().primaryKey().getKey() + "=? "; - jdbc.update(sql, entity.getKey().primaryKey().getValue()); + jdbc.update(sql, entity.getRefs().primaryKey().getValue()); } public Optional get(Key key, Class cls) throws NoSuchElementException { @@ -73,7 +73,7 @@ public Optional get(Key key, Class cls) throws NoSuchElementException { key.primaryKey().getValue()); Optional res = list.stream().findFirst(); - res.ifPresent(e -> e.setKey(key)); + res.ifPresent(e -> e.setRefs(key)); return res; } diff --git a/src/main/java/org/viablespark/persistence/Model.java b/src/main/java/org/viablespark/persistence/Model.java index 58da5d2..807b53b 100644 --- a/src/main/java/org/viablespark/persistence/Model.java +++ b/src/main/java/org/viablespark/persistence/Model.java @@ -16,15 +16,15 @@ import java.io.Serializable; public abstract class Model implements Persistable, Serializable { - private Key key; + private Key refs; @Override - public Key getKey() { - return key; + public Key getRefs() { + return refs; } @Override - public void setKey(Key key) { - this.key = key; + public void setRefs(Key refs) { + this.refs = refs; } } diff --git a/src/main/java/org/viablespark/persistence/Persistable.java b/src/main/java/org/viablespark/persistence/Persistable.java index 5614cd8..e2f76b6 100644 --- a/src/main/java/org/viablespark/persistence/Persistable.java +++ b/src/main/java/org/viablespark/persistence/Persistable.java @@ -15,16 +15,16 @@ public interface Persistable { - Key getKey(); + Key getRefs(); - void setKey(Key key); + void setRefs(Key refs); default Long getId() { - return getKey().primaryKey().getValue(); + return getRefs().primaryKey().getValue(); } default boolean isNew() { - return getKey() == null; + return getRefs() == null; } } diff --git a/src/main/java/org/viablespark/persistence/PersistableRowMapper.java b/src/main/java/org/viablespark/persistence/PersistableRowMapper.java index 025495b..7d7067d 100644 --- a/src/main/java/org/viablespark/persistence/PersistableRowMapper.java +++ b/src/main/java/org/viablespark/persistence/PersistableRowMapper.java @@ -66,7 +66,7 @@ public E mapRow(SqlRowSet rs, int rowNum) { private void assignPrimaryKey(Persistable e, ResultSet rs) throws Exception { if (persistableType.isAnnotationPresent(PrimaryKey.class)) { String primaryKeyName = e.getClass().getAnnotation(PrimaryKey.class).value(); - e.setKey(Key.of(primaryKeyName, rs.getLong(primaryKeyName))); + e.setRefs(Key.of(primaryKeyName, rs.getLong(primaryKeyName))); } } @@ -81,9 +81,9 @@ private void assignNamedFields(Persistable entity, ResultSet rs) throws Exceptio var optionMethod = WithSql.getAnnotation(m, entity.getClass(), Named.class); var customField = optionMethod.orElseThrow().value(); - - if (rs.getObject(customField) != null) { - var setterValue = rs.getObject(customField); + int index = columnIndex(rs,customField); + if (index > 0) { + var setterValue = rs.getObject(index); Method setterMethod = entity.getClass().getDeclaredMethod( m.getName().replace("get", "set"), m.getReturnType()); setterMethod.invoke(entity, interpolateValue(setterValue,m.getReturnType())); @@ -92,10 +92,28 @@ private void assignNamedFields(Persistable entity, ResultSet rs) throws Exceptio } } + private int columnIndex(ResultSet rs, String columnName ) throws SQLException{ + ResultSetMetaData metaData = rs.getMetaData(); + int columnCount = metaData.getColumnCount(); + int index = -1; + for (int i = 1; i <= columnCount; i++) { + if (metaData.getColumnName(i).equalsIgnoreCase(columnName)) { + index = i; + break; + } + } + return index; + } + private static Object interpolateValue(Object value, Class asType) { if( value instanceof Long && asType == Integer.class ){ value = Math.toIntExact((Long) value); } + + if( value instanceof Long && asType.isPrimitive() && asType == int.class){ + value = Math.toIntExact((Long) value); + } + return value; } @@ -115,7 +133,7 @@ private void assignForeignRefs(Persistable entity, ResultSet rs) throws Exceptio } var pkValue = rs.getLong(columnName); var fkInstance = foreignType.getDeclaredConstructor().newInstance(); - ((Persistable) fkInstance).setKey(Key.of(pkName, pkValue)); + ((Persistable) fkInstance).setRefs(Key.of(pkName, pkValue)); Method setterMethod = entity.getClass().getDeclaredMethod( m.getName().replace("get", "set"), foreignType); setterMethod.invoke(entity, fkInstance); diff --git a/src/main/java/org/viablespark/persistence/dsl/WithSql.java b/src/main/java/org/viablespark/persistence/dsl/WithSql.java index fc511f0..c2e8141 100644 --- a/src/main/java/org/viablespark/persistence/dsl/WithSql.java +++ b/src/main/java/org/viablespark/persistence/dsl/WithSql.java @@ -61,7 +61,7 @@ public static SqlClause getSQLUpdateClause(Persistable entity) throws SQLExcepti answers.add(deriveValue(m, entity)); } sql.deleteCharAt(sql.length() - 1); // remove last comma. - Pair primaryKey = entity.getKey().primaryKey(); + Pair primaryKey = entity.getRefs().primaryKey(); sql.append(" WHERE ").append(primaryKey.getKey()).append("=?"); answers.add(primaryKey.getValue()); @@ -108,7 +108,7 @@ private static String deriveName(Method m, Persistable entity) throws Exception Optional refOption = getAnnotation(m, entity.getClass(), Ref.class); if (refOption.isPresent()) { Persistable refObj = (Persistable) m.invoke(entity); - return refObj.getKey().primaryKey().getKey(); + return refObj.getRefs().primaryKey().getKey(); } String name = m.getName().substring(3); @@ -120,7 +120,7 @@ private static Object deriveValue(Method m, Persistable entity) throws Exception Optional refOption = getAnnotation(m, entity.getClass(), Ref.class); if (refOption.isPresent()) { Persistable refObj = (Persistable) m.invoke(entity); - return refObj.getKey().primaryKey().getValue(); + return refObj.getRefs().primaryKey().getValue(); } return m.invoke(entity); } @@ -134,7 +134,7 @@ private static String deriveNameForSelectClause(Method m, Class cls) { return namedOption.get().value(); } else { return namedOption.get().value() - + " as " + camelToSnake(m.getName().substring(3)); + + " as \""+camelToSnake(m.getName().substring(3))+"\""; } } @@ -190,4 +190,5 @@ private static String camelToSnake(String str) { return str; } + } diff --git a/src/test/java/org/viablespark/persistence/Contractor.java b/src/test/java/org/viablespark/persistence/Contractor.java index 730fff9..369409b 100644 --- a/src/test/java/org/viablespark/persistence/Contractor.java +++ b/src/test/java/org/viablespark/persistence/Contractor.java @@ -31,20 +31,20 @@ public class Contractor implements Persistable { private String email; @Override - public Key getKey() { + public Key getRefs() { return key; } @Override - public void setKey(Key key) { - this.key = key; + public void setRefs(Key refs) { + this.key = refs; } public Contractor() { } public Contractor(String key, Long id) { - setKey(Key.of(key,id)); + setRefs(Key.of(key,id)); } @Named("sc_name") diff --git a/src/test/java/org/viablespark/persistence/NoteRepositoryTest.java b/src/test/java/org/viablespark/persistence/NoteRepositoryTest.java index e0bf009..89e8581 100644 --- a/src/test/java/org/viablespark/persistence/NoteRepositoryTest.java +++ b/src/test/java/org/viablespark/persistence/NoteRepositoryTest.java @@ -19,6 +19,7 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.viablespark.persistence.dsl.SqlQuery; import java.math.BigDecimal; @@ -42,19 +43,30 @@ public void testInsertNote() throws Exception { progress.save(entity.getProgress()); var keyOption = repository.save(entity); - keyOption.ifPresent( key -> assertEquals(2L, key.primaryKey().getValue())); - assertEquals( 2L,entity.getProgress().getKey().primaryKey().getValue()); - assertEquals( "id",entity.getProgress().getKey().primaryKey().getKey()); + keyOption.ifPresent( key -> assertEquals(3L, key.primaryKey().getValue())); + assertEquals( 2L,entity.getProgress().getRefs().primaryKey().getValue()); + assertEquals( "id",entity.getProgress().getRefs().primaryKey().getKey()); } @Test public void testSelectNote() throws Exception { var found = repository.get(Key.of("n_key",1L),Note.class); - found.ifPresent( n -> assertEquals(1L, n.getKey().primaryKey().getValue())); - found.ifPresent( n -> assertNotNull( n.getProgress().getKey())); + found.ifPresent( n -> assertEquals(1L, n.getRefs().primaryKey().getValue())); + found.ifPresent( n -> assertNotNull( n.getProgress().getRefs())); } + + @Test + public void testQueryNote() throws Exception { + var found = repository.queryEntity(SqlQuery + .where(Pair.of("progress_id = ?", 1)) + .primaryKey("n_key"),Note.class); + + assertTrue( found.size() > 1); + } + + @BeforeEach public void setUp() { // creates an HSQL in-memory database populated from default scripts diff --git a/src/test/java/org/viablespark/persistence/PersistableRowMapperTest.java b/src/test/java/org/viablespark/persistence/PersistableRowMapperTest.java index 31fe3c1..0604fb3 100644 --- a/src/test/java/org/viablespark/persistence/PersistableRowMapperTest.java +++ b/src/test/java/org/viablespark/persistence/PersistableRowMapperTest.java @@ -38,7 +38,7 @@ public void testRowSetMapping(){ List resultSet = jdbc.query("select * from contractor order by sc_key asc", f); while( rowSet.next() ){ Contractor contractor = f.mapRow(rowSet, rowSet.getRow()); - assertEquals(contractor.getKey(),resultSet.get(rowSet.getRow()-1).getKey() ); + assertEquals(contractor.getRefs(),resultSet.get(rowSet.getRow()-1).getRefs() ); } } @@ -48,7 +48,7 @@ public void testMapRowMappingUsingResultSet() throws Exception { var jdbc = new JdbcTemplate(db); PersistableMapper f = (SqlRowSet rs, int rowNum) -> { Contractor c = new Contractor(); - c.setKey(Key.of("sc_key",rs.getLong("sc_key"))); + c.setRefs(Key.of("sc_key",rs.getLong("sc_key"))); c.setName(rs.getString("sc_name")); c.setContact(rs.getString("contact")); return c; @@ -63,7 +63,7 @@ public void testMapRowMappingUsingResultSet() throws Exception { var rs = statement.executeQuery(); rs.next(); Contractor entity = f.mapRow(rs,rs.getRow()); - assertEquals(entity.getKey(), list.get(rs.getRow()-1).getKey() ); + assertEquals(entity.getRefs(), list.get(rs.getRow()-1).getRefs() ); } } diff --git a/src/test/java/org/viablespark/persistence/Proposal.java b/src/test/java/org/viablespark/persistence/Proposal.java index 10332d9..d44e314 100644 --- a/src/test/java/org/viablespark/persistence/Proposal.java +++ b/src/test/java/org/viablespark/persistence/Proposal.java @@ -44,7 +44,7 @@ public Proposal() { } public Proposal(String key, Long id) { - super.setKey(Key.of(key, id)); + super.setRefs(Key.of(key, id)); } @Named("proposal_name") @@ -53,7 +53,7 @@ public String getPropName() { } public void setPr_key(Long id) { - setKey(Key.of("pr_key", id)); + setRefs(Key.of("pr_key", id)); } public void setPropName(String propName) { diff --git a/src/test/java/org/viablespark/persistence/ProposalMapper.java b/src/test/java/org/viablespark/persistence/ProposalMapper.java index fb16aa9..27eb3db 100644 --- a/src/test/java/org/viablespark/persistence/ProposalMapper.java +++ b/src/test/java/org/viablespark/persistence/ProposalMapper.java @@ -13,11 +13,8 @@ package org.viablespark.persistence; -import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet; import org.springframework.jdbc.support.rowset.SqlRowSet; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.LinkedHashMap; import java.util.Map; @@ -28,7 +25,7 @@ public class ProposalMapper implements PersistableMapper { @Override public Proposal mapRow(SqlRowSet rs, int rowNum) { var pr = new Proposal(); - pr.setKey(Key.of("pr_key", rs.getLong("pr_key"))); + pr.setRefs(Key.of("pr_key", rs.getLong("pr_key"))); pr.setDistance(rs.getInt("dist")); pr.setPropName(rs.getString("proposal_name")); if (rs.getObject("sc_key") != null) { diff --git a/src/test/java/org/viablespark/persistence/ProposalRepositoryTest.java b/src/test/java/org/viablespark/persistence/ProposalRepositoryTest.java index f2a88ea..672df39 100644 --- a/src/test/java/org/viablespark/persistence/ProposalRepositoryTest.java +++ b/src/test/java/org/viablespark/persistence/ProposalRepositoryTest.java @@ -90,7 +90,7 @@ public void testSave() throws Exception { @Test public void testDelete() { Proposal e = new Proposal(); - e.setKey(Key.of("pr_key", 1L)); + e.setRefs(Key.of("pr_key", 1L)); repository.delete(e); logger.info("Entity Deleted"); } @@ -99,7 +99,7 @@ public void testDelete() { public void testGet() { Optional result = repository.get(Key.of("pr_key", 1L), Proposal.class); assertTrue(result.isPresent()); - assertEquals(1L, result.get().getKey().primaryKey().getValue()); + assertEquals(1L, result.get().getRefs().primaryKey().getValue()); } @Test diff --git a/src/test/java/org/viablespark/persistence/ProposalTaskRepositoryTest.java b/src/test/java/org/viablespark/persistence/ProposalTaskRepositoryTest.java index 7a9622e..1fda216 100644 --- a/src/test/java/org/viablespark/persistence/ProposalTaskRepositoryTest.java +++ b/src/test/java/org/viablespark/persistence/ProposalTaskRepositoryTest.java @@ -49,7 +49,7 @@ public void testInsertWithPKnoAutoGenerate() throws Exception { repository.getProposal(1L).ifPresent(entity::setProposal); var keyOption = repository.save(entity); - entity.setKey( entity.getTask().getKey() ); //composite pk - Not auto-generated + entity.setRefs( entity.getTask().getRefs() ); //composite pk - Not auto-generated keyOption.ifPresent( key -> assertEquals(1L, key.primaryKey().getValue())); } diff --git a/src/test/java/org/viablespark/persistence/dsl/WithSqlTest.java b/src/test/java/org/viablespark/persistence/dsl/WithSqlTest.java index 75501b0..74a2056 100644 --- a/src/test/java/org/viablespark/persistence/dsl/WithSqlTest.java +++ b/src/test/java/org/viablespark/persistence/dsl/WithSqlTest.java @@ -13,7 +13,6 @@ package org.viablespark.persistence.dsl; -import org.springframework.jdbc.support.rowset.SqlRowSet; import org.viablespark.persistence.Contractor; import org.viablespark.persistence.Key; import java.util.Date; @@ -37,17 +36,17 @@ public WithSqlTest() { @Test public void testGetSQLSelectClause() { String select = WithSql.getSQLSelectClause(Proposal.class); - assertEquals("sc_key,dist as distance,prop_date,prop_id,proposal_name as prop_name,submit_deadline", select); + assertEquals("sc_key,dist as \"distance\",prop_date,prop_id,proposal_name as \"prop_name\",submit_deadline", select); String notesSelect = WithSql.getSQLSelectClause(Note.class,"n_key"); - assertEquals("n_key,additional as extra,note as note_content,progress_id", notesSelect); + assertEquals("n_key,additional as \"extra\",note as \"note_content\",progress_id", notesSelect); } @Test public void testGetSQLUpdateClause() throws Exception { Proposal e = new Proposal(); - e.setKey( Key.of("pri_key",233L) ); + e.setRefs( Key.of("pri_key",233L) ); e.setDistance(344); e.setPropDate(new Date()); e.setPropId("propId"); @@ -76,7 +75,7 @@ public void testGetSQLUpdateClause() throws Exception { @Test public void testGetSQLInsertClause() throws Exception { Proposal e = new Proposal(); - e.setKey(Key.of("pri_key",233L)); + e.setRefs(Key.of("pri_key",233L)); e.setDistance(344); e.setPropDate(new Date()); e.setPropId("propId"); diff --git a/src/test/resources/data.sql b/src/test/resources/data.sql index f110609..477a1b9 100644 --- a/src/test/resources/data.sql +++ b/src/test/resources/data.sql @@ -28,3 +28,4 @@ INSERT INTO proposal_task (t_key,pr_key,price ) VALUES (2,1,300); INSERT INTO progress(percent) VALUES (50); INSERT INTO note (note,note_date,additional,progress_id) VALUES('note1', curdate(),'additional',1); +INSERT INTO note (note,note_date,additional,progress_id) VALUES('note2', curdate(),'additional2',1);