Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/main/java/org/j8ql/PStmt.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,18 @@ public int[] executeBatch(List<List> valuesArray) throws RSQLException{
throw new RSQLException(e,sql);
}
}

public List<Record> getGeneratedKeys() throws RSQLException{
List<Record> list;
ResultSet rs;
try{
rs = pstmt.getGeneratedKeys();
list = db.buildResults(rs);
return list;
}catch (SQLException e) {
throw new RSQLException(e,sql);
}
}
// --------- /Low Level Execute --------- //

// --------- List --------- //
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/j8ql/Runner.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public interface Runner extends AutoCloseable {

int[] executeBatch(InsertQuery builder);

List<Record> getGeneratedKeys();

// --------- SQL Query APIs --------- //
<T> List<T> list(Class<T> cls, String sql, Object... values);

Expand Down Expand Up @@ -84,6 +86,8 @@ public interface Runner extends AutoCloseable {

// --------- Stmt Factory --------- //
PStmt newPQuery(String sql);

PStmt newPQuery(String sql, int autoGeneratedKeys);
// --------- /Stmt Factory --------- //

// --------- Transaction --------- //
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/j8ql/RunnerException.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public class RunnerException extends BaseException{
public enum RunnerError implements BaseException.Error {
DML_BUILDER_HAS_NO_RETURNING_CANNOT_BE_STREAMED("This UpdateQuery does not have any returning and therefore cannot be streamed or listed"),
INCOMPLETE_INSERT_BUILDER_NO_COLUMNS_OR_VALUE_OBJECT("This inserBuilder does not contain columns or a values object, not sure what to insert."),
CANNOT_BATCH_DOES_NOT_HAVE_BATCH_VALUE("This builder cannot be batchExecuted because it does not contain a batchValue or batchValues");
CANNOT_BATCH_DOES_NOT_HAVE_BATCH_VALUE("This builder cannot be batchExecuted because it does not contain a batchValue or batchValues"),
CANNOT_GETKEYS_DOES_NOT_HAVE_PREPARED_STATEMENT("This builder doesn't have PreparedStatement");

String msg;
RunnerError(String msg) {
Expand Down
27 changes: 25 additions & 2 deletions src/main/java/org/j8ql/RunnerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
Expand All @@ -28,9 +29,11 @@ public class RunnerImpl implements Runner {
// Since the db is final, it cannot be changed, so, safe to give public access.
public final DB db;

private List<Record> batchResult;
RunnerImpl(DB db, Connection con) {
this.con = con;
this.db = db;
this.batchResult = null;
}

// --------- Count --------- //
Expand Down Expand Up @@ -155,12 +158,20 @@ public int[] executeBatch(InsertQuery builder) {
if (builder.getBatchValues() == null && builder.getBatchObjects() == null){
throw new RunnerException(RunnerError.CANNOT_BATCH_DOES_NOT_HAVE_BATCH_VALUE);
}
int[] r;
String sql = db.sql(builder);
List<List> batchValues = db.batchValues(builder);
try (PStmt query = newPQuery(sql)) {
return query.executeBatch(batchValues);
try (PStmt query = newPQuery(sql, Statement.RETURN_GENERATED_KEYS)) {
r = query.executeBatch(batchValues);
this.batchResult = query.getGeneratedKeys();
return r;
}
}

@Override
public List<Record> getGeneratedKeys() {
return this.batchResult;
}
// --------- /batch --------- //

// --------- Private Helpers --------- //
Expand Down Expand Up @@ -282,6 +293,18 @@ public PStmt newPQuery(String sql) {
throw new RSQLException(e);
}
}

@Override
public PStmt newPQuery(String sql, int autoGeneratedKeys) {
try {
PreparedStatement pstmt;
pstmt = con.prepareStatement(sql, autoGeneratedKeys);

return new PStmt(db, sql, pstmt);
} catch (SQLException e) {
throw new RSQLException(e);
}
}
// --------- /Stmt Factory --------- //

// --------- Transaction --------- //
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/org/j8ql/RunnerProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ public int[] executeBatch(InsertQuery builder) {
return runner.executeBatch(builder);
}

@Override
public List<Record> getGeneratedKeys() { return runner.getGeneratedKeys(); }

@Override
public <T> List<T> list(Class<T> cls, String sql, Object... values) {
return runner.list(cls, sql, values);
Expand Down Expand Up @@ -132,6 +135,9 @@ public PStmt newPQuery(String sql) {
return runner.newPQuery(sql);
}

@Override
public PStmt newPQuery(String sql, int autoGeneratedKeys) { return runner.newPQuery(sql, autoGeneratedKeys); }

@Override
public Runner startTransaction() {
return runner.startTransaction();
Expand Down
34 changes: 34 additions & 0 deletions src/test/java/org/j8ql/test/GetGeneratedKeysTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.j8ql.test;

import org.j8ql.DB;
import org.j8ql.DBBuilder;
import org.j8ql.Record;
import org.j8ql.Runner;
import org.j8ql.query.InsertQuery;
import org.j8ql.query.Query;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.j8ql.query.Query.select;
import static org.junit.Assert.assertEquals;

public class GetGeneratedKeysTest extends TestSupport {
@Test
public void testBatchInsertToFetchGeneratedKeys() {
DB db = new DBBuilder().build(dataSource);

try (Runner runner = db.openRunner()) {
Object[][] data = {{"ticket 01 testBatchInsertToFetchGeneratedKeys"}, {"ticket 02 testBatchInsertToFetchGeneratedKeys"}};
List<List> batchValues = Stream.of(data).map(Arrays::asList).collect(Collectors.toList());
InsertQuery<Integer> insert = Query.insert("ticket").columns("subject");
runner.executeBatch(insert.batchValues(batchValues));
List<Record> generatedKeys = runner.getGeneratedKeys();
assertEquals(2, runner.count(select("ticket")));
assertEquals(2, generatedKeys.size());
}
}
}
2 changes: 1 addition & 1 deletion src/test/java/org/j8ql/test/ReadmeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public void fullTextSearchExample() {
// NOTE 1: You can add third part (with the second ";") and in this case, it will be columnNameOrFunction;operator;valueFunction
// NOTE 2: The first "columnName" can be a function, and in this case, it won't be escaped;
// NOTE 3: the last ";to_tsquery(?)" allow to optionally add a function value to the query (which is what we need for tsv search).
SelectQuery<Ticket> tsvSelect = Query.select(Ticket.class).where("to_tsvector(ticket.subject);@@;to_tsquery(?)", "management");
SelectQuery<Ticket> tsvSelect = Query.select(Ticket.class).where("to_tsvector(ticket.subject);@@;to_tsquery(?)", "manager");
System.out.println("sql: " + db.sql(tsvSelect));
// sql: select "ticket".* from "ticket" where to_tsvector(ticket.subject) @@ to_tsquery(?)

Expand Down
4 changes: 2 additions & 2 deletions src/test/java/org/j8ql/test/TsvTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ public void simpleTsvSearch(){
}

// raw SQL tsv search (postgres tsv search will match "management" with "manager", as both have the "manag" lexeme)
List<Record> recordsFromSql = runner.list("select subject from ticket where to_tsvector(subject) @@ to_tsquery(?)","management");
List<Record> recordsFromSql = runner.list("select subject from ticket where to_tsvector(subject) @@ to_tsquery(?)","manager");
assertEquals(2, recordsFromSql.size());

// same, will
SelectQuery<Record> selectQuery = Query.select("ticket").columns("subject").where("to_tsvector(subject);@@;to_tsquery(?)","management");
SelectQuery<Record> selectQuery = Query.select("ticket").columns("subject").where("to_tsvector(subject);@@;to_tsquery(?)","manager");
List<Record> recordsFromSelectQuery = runner.list(selectQuery);
assertEquals(2, recordsFromSelectQuery.size());

Expand Down