Skip to content

Commit

Permalink
Improve compatibility with Kotlin and Json serialization. (#11)
Browse files Browse the repository at this point in the history
* Improve compatibility with Kotlin and Json serialization. Persistable Model key changed to ref declaration for more intuitive payload signature.

* commit badge

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
martin-jamszolik and github-actions[bot] authored Jan 27, 2023
1 parent d5f2293 commit 9890c49
Show file tree
Hide file tree
Showing 17 changed files with 82 additions and 54 deletions.
2 changes: 1 addition & 1 deletion .github/badges/branches.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion .github/badges/jacoco.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ plugins {
}

group = "org.viablespark"
version = "1.4.0"
version = "1.5.0"

repositories {
mavenCentral()
Expand Down Expand Up @@ -75,7 +75,7 @@ publishing {
create<MavenPublication>("maven") {
groupId = "org.viablespark"
artifactId = "goodenough-jdbc"
version = "1.4.0"
version = "1.5.0"

from(components["java"])
pom {
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/org/viablespark/persistence/BaseRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,26 @@ public Optional<Key> 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);
String sql = "UPDATE " + deriveEntityName(entity.getClass()) + " "
+ 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<E> get(Key key, Class<E> cls) throws NoSuchElementException {
Expand All @@ -73,7 +73,7 @@ public Optional<E> get(Key key, Class<E> cls) throws NoSuchElementException {
key.primaryKey().getValue());

Optional<E> res = list.stream().findFirst();
res.ifPresent(e -> e.setKey(key));
res.ifPresent(e -> e.setRefs(key));
return res;
}

Expand Down
10 changes: 5 additions & 5 deletions src/main/java/org/viablespark/persistence/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
8 changes: 4 additions & 4 deletions src/main/java/org/viablespark/persistence/Persistable.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
}
}

Expand All @@ -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()));
Expand All @@ -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;
}

Expand All @@ -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);
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/org/viablespark/persistence/dsl/WithSql.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Long> primaryKey = entity.getKey().primaryKey();
Pair<String, Long> primaryKey = entity.getRefs().primaryKey();
sql.append(" WHERE ").append(primaryKey.getKey()).append("=?");
answers.add(primaryKey.getValue());

Expand Down Expand Up @@ -108,7 +108,7 @@ private static String deriveName(Method m, Persistable entity) throws Exception
Optional<Ref> 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);
Expand All @@ -120,7 +120,7 @@ private static Object deriveValue(Method m, Persistable entity) throws Exception
Optional<Ref> 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);
}
Expand All @@ -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))+"\"";
}
}

Expand Down Expand Up @@ -190,4 +190,5 @@ private static String camelToSnake(String str) {
return str;
}


}
8 changes: 4 additions & 4 deletions src/test/java/org/viablespark/persistence/Contractor.java
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
22 changes: 17 additions & 5 deletions src/test/java/org/viablespark/persistence/NoteRepositoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public void testRowSetMapping(){
List<Contractor> 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() );
}
}

Expand All @@ -48,7 +48,7 @@ public void testMapRowMappingUsingResultSet() throws Exception {
var jdbc = new JdbcTemplate(db);
PersistableMapper<Contractor> 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;
Expand All @@ -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() );
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/viablespark/persistence/Proposal.java
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -28,7 +25,7 @@ public class ProposalMapper implements PersistableMapper<Proposal> {
@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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand All @@ -99,7 +99,7 @@ public void testDelete() {
public void testGet() {
Optional<Proposal> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}

Expand Down
Loading

0 comments on commit 9890c49

Please sign in to comment.