+ * query(() -> "SELECT * FROM players;");
+ *
+ * @param query The query to use while constructing query string.
+ * @param typeClass Type class of object which will be instantiated and
+ * populated with column values.
+ * @param Type of objects in result.
+ *
+ * @return Collection of row objects.
*/
@Override
public QueryRowsResult query(Query query, Class typeClass) {
+ Objects.requireNonNull(query);
+ Objects.requireNonNull(typeClass);
+
QueryRowsResult resultRows = query(query.getAncestor());
QueryRowsResult result = new QueryRowsResult<>(resultRows.isSuccessful());
@@ -165,7 +210,9 @@ public QueryRowsResult query(Query query, Class typeClass) {
}
/**
- * @see SQLDatabaseConnectionImpl#query(Query, Class)
+ * Performs new query and returns the result. This result is never null.
+ *
+ * @see SQLDatabaseConnection#query(Query, Class)
*/
@Override
public QueryRowsResult query(Query query) {
@@ -200,7 +247,14 @@ public QueryRowsResult query(Query query) {
}
/**
- * @see SQLDatabaseConnection#exec(Query)
+ * Executes given query and returns execution result.
+ * This result does not contain any rows. If you want to
+ * execute query return result of rows, see method
+ * {@link SQLDatabaseConnection#query(Query)}
+ *
+ * @param query Query to use for building query string.
+ * @return Blank rows result that only informs
+ * about success state of the request.
*/
public QueryResult exec(Query query) {
if(!handleAutoReconnect()) {
@@ -216,7 +270,14 @@ public QueryResult exec(Query query) {
}
/**
- * @see SQLDatabaseConnection#save(String, Object)
+ * Saves this mapping object into database using upsert query.
+ *
+ * All mapping strategies are described in:
+ * {@link SQLDatabaseConnection#query(Query, Class)}.
+ *
+ * @param table Table to save into.
+ * @param obj The object to save.
+ * @return Result of the query.
*/
@Override
public QueryResult save(String table, Object obj) { // by default, it creates and upsert request.
@@ -285,6 +346,7 @@ protected Pair buildDefsVals(Object obj) {
return new Pair<>(defs, vals);
}
+ @SuppressWarnings("all")
private boolean handleAutoReconnect() {
if(options.isAutoReconnect() && !isConnected()) {
debug("Trying to make a new connection with the database!");
@@ -296,6 +358,8 @@ private boolean handleAutoReconnect() {
return true;
}
+ // --***-- Query builders --***--
+
public SelectQuery select(String... cols) {
return new SelectQuery(this, cols);
}
@@ -367,6 +431,16 @@ public boolean isDebug() {
return options.isDebug();
}
+ public final SQLDatabaseOptions cloneOptions() {
+ SQLDatabaseOptions cloned = new SQLDatabaseOptions();
+ cloned.setDebug(options.isDebug());
+ cloned.setLogSqlErrors(options.isLogSqlErrors());
+ cloned.setNamingStrategy(options.getNamingStrategy());
+ cloned.setGson(options.getGson());
+ cloned.setAutoReconnect(options.isAutoReconnect());
+ return cloned;
+ }
+
@SuppressWarnings("unchecked")
private PreparedStatement buildStatement(Query query) throws SQLException {
StatementFactory factory = new DefaultStatementFactory(query);
diff --git a/core/src/main/java/me/zort/sqllib/internal/query/QueryNode.java b/core/src/main/java/me/zort/sqllib/internal/query/QueryNode.java
index 91635bd..0f7305b 100644
--- a/core/src/main/java/me/zort/sqllib/internal/query/QueryNode.java
+++ b/core/src/main/java/me/zort/sqllib/internal/query/QueryNode.java
@@ -36,6 +36,15 @@ public QueryNode(@Nullable P parent, List> initial, int priority) {
this.details = new ConcurrentHashMap<>();
}
+ /**
+ * Builds the query string with placeholders containing values
+ * for passing into PreparedStatement.
+ *
+ * Query example: SELECT * FROM table WHERE id = <id>;
+ * Values example: [AnyId]
+ *
+ * @return QueryDetails object.
+ */
public abstract QueryDetails buildQueryDetails();
@Override
diff --git a/core/src/main/java/me/zort/sqllib/mapping/QueryAnnotation.java b/core/src/main/java/me/zort/sqllib/mapping/QueryAnnotation.java
index 791c269..ae6db2c 100644
--- a/core/src/main/java/me/zort/sqllib/mapping/QueryAnnotation.java
+++ b/core/src/main/java/me/zort/sqllib/mapping/QueryAnnotation.java
@@ -7,6 +7,7 @@
import me.zort.sqllib.internal.query.QueryNode;
import me.zort.sqllib.mapping.annotation.*;
import me.zort.sqllib.mapping.builder.DeleteQueryBuilder;
+import me.zort.sqllib.mapping.builder.InsertQueryBuilder;
import me.zort.sqllib.mapping.builder.SaveQueryBuilder;
import me.zort.sqllib.mapping.builder.SelectQueryBuilder;
import me.zort.sqllib.mapping.exception.SQLMappingException;
@@ -40,6 +41,7 @@ public class QueryAnnotation {
QUERY_ANNOT.put(Select.class, new QueryAnnotation(true, new SelectQueryBuilder()));
QUERY_ANNOT.put(Delete.class, new QueryAnnotation(false, new DeleteQueryBuilder()));
QUERY_ANNOT.put(Save.class, new QueryAnnotation(false, new SaveQueryBuilder()));
+ QUERY_ANNOT.put(Insert.class, new QueryAnnotation(false, new InsertQueryBuilder()));
// TODO: Populate
}
@@ -66,10 +68,6 @@ public interface QueryBuilder {
}
public static class Validator {
- public static void requireTableDefinition(Method method, PlaceholderMapper placeholderMapper) {
- if (Table.Util.getFromContext(method, placeholderMapper) == null)
- throw new SQLMappingException("Method " + method.getName() + " requires @Table annotation", method, null);
- }
public static void requireWhereDefinition(Method method) {
if (!method.isAnnotationPresent(Where.class))
throw new SQLMappingException("Method " + method.getName() + " requires @Where annotation", method, null);
diff --git a/core/src/main/java/me/zort/sqllib/mapping/annotation/Insert.java b/core/src/main/java/me/zort/sqllib/mapping/annotation/Insert.java
new file mode 100644
index 0000000..69fc910
--- /dev/null
+++ b/core/src/main/java/me/zort/sqllib/mapping/annotation/Insert.java
@@ -0,0 +1,15 @@
+package me.zort.sqllib.mapping.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Insert {
+
+ String[] cols();
+ String[] vals();
+
+}
diff --git a/core/src/main/java/me/zort/sqllib/mapping/annotation/Table.java b/core/src/main/java/me/zort/sqllib/mapping/annotation/Table.java
index d405b70..767e9b9 100644
--- a/core/src/main/java/me/zort/sqllib/mapping/annotation/Table.java
+++ b/core/src/main/java/me/zort/sqllib/mapping/annotation/Table.java
@@ -1,6 +1,9 @@
package me.zort.sqllib.mapping.annotation;
import me.zort.sqllib.mapping.PlaceholderMapper;
+import me.zort.sqllib.mapping.QueryAnnotation;
+import me.zort.sqllib.mapping.exception.SQLMappingException;
+import me.zort.sqllib.util.ParameterPair;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.ElementType;
@@ -16,13 +19,14 @@
class Util {
@Nullable
- public static String getFromContext(Method method, PlaceholderMapper mapper) {
+ public static String getFromContext(Method method, ParameterPair[] parameters) {
+ PlaceholderMapper mapper = new PlaceholderMapper(parameters);
if (method.isAnnotationPresent(Table.class)) {
return mapper.assignValues(method.getAnnotation(Table.class).value());
} else if(method.getDeclaringClass().isAnnotationPresent(Table.class)) {
return mapper.assignValues(method.getDeclaringClass().getAnnotation(Table.class).value());
} else {
- return null;
+ throw new SQLMappingException("Method " + method.getName() + " requires @Table annotation", method, null);
}
}
}
diff --git a/core/src/main/java/me/zort/sqllib/mapping/builder/DeleteQueryBuilder.java b/core/src/main/java/me/zort/sqllib/mapping/builder/DeleteQueryBuilder.java
index 0e808a3..50b1e80 100644
--- a/core/src/main/java/me/zort/sqllib/mapping/builder/DeleteQueryBuilder.java
+++ b/core/src/main/java/me/zort/sqllib/mapping/builder/DeleteQueryBuilder.java
@@ -19,8 +19,7 @@ public class DeleteQueryBuilder implements QueryAnnotation.QueryBuilder
@Override
public QueryNode> build(SQLConnection connection, Delete queryAnnotation, Method method, ParameterPair[] parameters) {
PlaceholderMapper placeholderMapper = new PlaceholderMapper(parameters);
- QueryAnnotation.Validator.requireTableDefinition(method, placeholderMapper);
- String table = Table.Util.getFromContext(method, placeholderMapper);
+ String table = Table.Util.getFromContext(method, parameters);
QueryNode> node = new DeleteQuery(null, table);
if (method.isAnnotationPresent(Where.class)) {
diff --git a/core/src/main/java/me/zort/sqllib/mapping/builder/InsertQueryBuilder.java b/core/src/main/java/me/zort/sqllib/mapping/builder/InsertQueryBuilder.java
new file mode 100644
index 0000000..1ac0e61
--- /dev/null
+++ b/core/src/main/java/me/zort/sqllib/mapping/builder/InsertQueryBuilder.java
@@ -0,0 +1,35 @@
+package me.zort.sqllib.mapping.builder;
+
+import me.zort.sqllib.SQLDatabaseConnection;
+import me.zort.sqllib.api.SQLConnection;
+import me.zort.sqllib.internal.query.InsertQuery;
+import me.zort.sqllib.internal.query.QueryNode;
+import me.zort.sqllib.mapping.PlaceholderMapper;
+import me.zort.sqllib.mapping.QueryAnnotation;
+import me.zort.sqllib.mapping.annotation.Insert;
+import me.zort.sqllib.mapping.annotation.Table;
+import me.zort.sqllib.util.ParameterPair;
+
+import java.lang.reflect.Method;
+
+public class InsertQueryBuilder implements QueryAnnotation.QueryBuilder {
+ @Override
+ public QueryNode> build(SQLConnection connection, Insert queryAnnotation, Method method, ParameterPair[] parameters) {
+ if (!(connection instanceof SQLDatabaseConnection))
+ throw new IllegalArgumentException("The connection must be a SQLDatabaseConnection");
+
+ String table = Table.Util.getFromContext(method, parameters);
+ InsertQuery query = ((SQLDatabaseConnection) connection).insert();
+ query.into(table, queryAnnotation.cols());
+
+ PlaceholderMapper mapper = new PlaceholderMapper(parameters);
+
+ String[] vals = queryAnnotation.vals();
+ for (int i = 0; i < vals.length; i++) {
+ vals[i] = mapper.assignValues(vals[i]);
+ }
+
+ query.values((Object[]) vals);
+ return query;
+ }
+}
diff --git a/core/src/main/java/me/zort/sqllib/mapping/builder/SaveQueryBuilder.java b/core/src/main/java/me/zort/sqllib/mapping/builder/SaveQueryBuilder.java
index 0a55038..86c1187 100644
--- a/core/src/main/java/me/zort/sqllib/mapping/builder/SaveQueryBuilder.java
+++ b/core/src/main/java/me/zort/sqllib/mapping/builder/SaveQueryBuilder.java
@@ -5,7 +5,6 @@
import me.zort.sqllib.api.SQLConnection;
import me.zort.sqllib.internal.query.QueryNode;
import me.zort.sqllib.internal.query.UpsertQuery;
-import me.zort.sqllib.mapping.PlaceholderMapper;
import me.zort.sqllib.mapping.QueryAnnotation;
import me.zort.sqllib.mapping.annotation.Save;
import me.zort.sqllib.mapping.annotation.Table;
@@ -19,9 +18,7 @@ public QueryNode> build(SQLConnection connection, Save queryAnnotation, Method
if (!(connection instanceof SQLDatabaseConnectionImpl))
throw new IllegalArgumentException("The connection must be an instance of SQLDatabaseConnectionImpl");
- PlaceholderMapper placeholderMapper = new PlaceholderMapper(parameters);
- QueryAnnotation.Validator.requireTableDefinition(method, placeholderMapper);
- String table = Table.Util.getFromContext(method, placeholderMapper);
+ String table = Table.Util.getFromContext(method, parameters);
UpsertQuery query = ((SQLDatabaseConnectionImpl) connection).save(getSaveableObject(parameters));
query.table(table);
diff --git a/core/src/main/java/me/zort/sqllib/mapping/builder/SelectQueryBuilder.java b/core/src/main/java/me/zort/sqllib/mapping/builder/SelectQueryBuilder.java
index 8228550..1b86da2 100644
--- a/core/src/main/java/me/zort/sqllib/mapping/builder/SelectQueryBuilder.java
+++ b/core/src/main/java/me/zort/sqllib/mapping/builder/SelectQueryBuilder.java
@@ -21,8 +21,7 @@ public class SelectQueryBuilder implements QueryAnnotation.QueryBuilder