├── .circleci
└── config.yml
├── .gitignore
├── LICENSE
├── README.md
├── pom.xml
└── src
├── main
└── java
│ └── com
│ └── rqlite
│ ├── NodeUnavailableException.java
│ ├── Rqlite.java
│ ├── RqliteFactory.java
│ ├── dto
│ ├── ExecuteResults.java
│ ├── GenericResults.java
│ ├── ParameterizedStatement.java
│ ├── Pong.java
│ └── QueryResults.java
│ └── impl
│ ├── ExecuteRequest.java
│ ├── GenericRequest.java
│ ├── ParameterizedStatementContent.java
│ ├── PingRequest.java
│ ├── QueryRequest.java
│ ├── RequestFactory.java
│ ├── RqliteImpl.java
│ └── RqliteNode.java
└── test
└── java
└── com
└── rqlite
├── RqliteClientTest.java
├── RqliteFactoryTest.java
├── RqliteFailoverTest.java
└── impl
└── RequestFactoryTest.java
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | # Java Gradle CircleCI 2.0 configuration file
2 | # See: https://circleci.com/docs/language-java/
3 | version: 2
4 |
5 | # Define a job to be invoked later in a workflow.
6 | # See: https://circleci.com/docs/configuration-reference/#jobs
7 | jobs:
8 | build:
9 | # Specify the execution environment. You can specify an image from Dockerhub or use one of our Convenience Images from CircleCI's Developer Hub.
10 | # See: https://circleci.com/docs/configuration-reference/#docker-machine-macos-windows-executor
11 | docker:
12 | # specify the version you desire here
13 | - image: circleci/openjdk:8-jdk
14 | - image: rqlite/rqlite:latest
15 |
16 | # Specify service dependencies here if necessary
17 | # CircleCI maintains a library of pre-built images
18 | # documented at https://circleci.com/docs/circleci-images/
19 | # - image: circleci/postgres:9.4
20 |
21 | working_directory: ~/repo
22 |
23 | environment:
24 | # Customize the JVM maximum heap limit
25 | JVM_OPTS: -Xmx3200m
26 | TERM: dumb
27 | # Add steps to the job
28 | # See: https://circleci.com/docs/configuration-reference/#steps
29 | steps:
30 | - checkout
31 |
32 | # Download and cache dependencies
33 | - restore_cache:
34 | keys:
35 | - v1-dependencies-{{ checksum "build.gradle" }}
36 | # fallback to using the latest cache if no exact match is found
37 | - v1-dependencies-
38 |
39 | - run: gradle dependencies
40 |
41 | - save_cache:
42 | paths:
43 | - ~/.gradle
44 | key: v1-dependencies-{{ checksum "build.gradle" }}
45 |
46 | # run tests!
47 | - run: gradle test
48 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 |
24 | .classpath
25 | .project
26 | .settings/
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 rqlite http://www.rqlite.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rqlite-java
2 | [](https://groups.google.com/group/rqlite)
3 |
4 | This is a basic Java client library for [rqlite](https://github.com/rqlite/rqlite). rqlite is a lightweight, distributed relational database, which uses SQLite as its storage engine. Significant development and testing remains, and pull requests are welcome.
5 |
6 | ## Quick start
7 | ```java
8 | // Declare variables.
9 | ExecuteResults results = null;
10 | QueryResults rows = null;
11 |
12 | // Get a connection to a rqlite node.
13 | Rqlite rqlite = RqliteFactory.connect("http", "localhost", 4001);
14 |
15 | // Create a table.
16 | results = rqlite.Execute("CREATE TABLE foo (id integer not null primary key, name text)");
17 | System.out.println(results.toString());
18 |
19 | // Insert a record.
20 | results = rqlite.Execute("INSERT INTO foo(name) VALUES(\"fiona\")");
21 | System.out.println(results.toString());
22 |
23 | // Query all records in the table.
24 | rows = rqlite.Query("SELECT * FROM foo", Rqlite.ReadConsistencyLevel.WEAK);
25 | System.out.println(rows.toString());
26 | ```
27 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 | com.rqlite
4 | rqlite-java
5 | 0.0.1-SNAPSHOT
6 |
7 |
8 |
9 | org.apache.maven.plugins
10 | maven-compiler-plugin
11 |
12 | 8
13 | 8
14 |
15 |
16 |
17 |
18 | rqlite Java client
19 | A Java client for rqlite, the lightweight, distributed relational database built on SQLite
20 |
21 |
22 | com.google.http-client
23 | google-http-client
24 | 1.22.0
25 |
26 |
27 | com.google.http-client
28 | google-http-client-jackson2
29 | 1.36.0
30 |
31 |
32 | junit
33 | junit
34 | 4.13.1
35 | test
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/NodeUnavailableException.java:
--------------------------------------------------------------------------------
1 | package com.rqlite;
2 |
3 | /**
4 | * This exception is thrown when rqlite-java cannot connect to a rqlite node.
5 | **/
6 | public class NodeUnavailableException extends Exception {
7 | public NodeUnavailableException(String message){
8 | super(message);
9 | }
10 | }
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/Rqlite.java:
--------------------------------------------------------------------------------
1 | package com.rqlite;
2 |
3 | import com.rqlite.dto.ExecuteResults;
4 | import com.rqlite.dto.ParameterizedStatement;
5 | import com.rqlite.dto.Pong;
6 | import com.rqlite.dto.QueryResults;
7 |
8 | public interface Rqlite {
9 |
10 | /**
11 | * ReadConsistencyLevel specifies the consistency level of a query.
12 | */
13 | public enum ReadConsistencyLevel {
14 | /** Node queries local SQLite database. */
15 | NONE("none"),
16 |
17 | /** Node performs leader check using master state before querying. */
18 | WEAK("weak"),
19 |
20 | /** Node performs leader check through the Raft system before querying */
21 | STRONG("strong");
22 |
23 | private final String value;
24 |
25 | private ReadConsistencyLevel(final String value) {
26 | this.value = value;
27 | }
28 |
29 | public String value() {
30 | return this.value;
31 | }
32 | }
33 |
34 | /** Query executes a single statement that returns rows. */
35 | public QueryResults Query(String q, ReadConsistencyLevel lvl) throws NodeUnavailableException;
36 |
37 | /** Query executes a single paramaterized statement that returns rows. */
38 | public QueryResults Query(ParameterizedStatement q, ReadConsistencyLevel lvl) throws NodeUnavailableException;
39 |
40 | /** Query executes multiple statement that returns rows. */
41 | public QueryResults Query(String[] q, boolean tx, ReadConsistencyLevel lvl) throws NodeUnavailableException;
42 |
43 | /** Query executes multiple paramaterized statement that returns rows. */
44 | public QueryResults Query(ParameterizedStatement[] q, boolean tx, ReadConsistencyLevel lvl) throws NodeUnavailableException;
45 |
46 | /** Execute executes a single statement that does not return rows. */
47 | public ExecuteResults Execute(String q) throws NodeUnavailableException;
48 |
49 | /** Execute executes a single paramaterized statement that does not return rows. */
50 | public ExecuteResults Execute(ParameterizedStatement q) throws NodeUnavailableException;
51 |
52 | /** Execute executes multiple statement that do not return rows. */
53 | public ExecuteResults Execute(String[] q, boolean tx) throws NodeUnavailableException;
54 |
55 | /** Execute executes multiple paramaterized statement that do not return rows. */
56 | public ExecuteResults Execute(ParameterizedStatement[] q, boolean tx) throws NodeUnavailableException;
57 |
58 | // Ping checks communication with the rqlite node. */
59 | public Pong Ping();
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/RqliteFactory.java:
--------------------------------------------------------------------------------
1 | package com.rqlite;
2 |
3 | import com.rqlite.impl.RqliteImpl;
4 |
5 | public enum RqliteFactory {
6 | INSTANCE;
7 |
8 | /**
9 | * Create a connection to a rqlite node.
10 | *
11 | * @param proto
12 | * the protocol, either "http" or "https"
13 | * @param host
14 | * the host name of the rqlite note
15 | * @param port
16 | * the port on the rqlite node
17 | * @return a rqlite client instance.
18 | */
19 | public static Rqlite connect(final String proto, final String host, final Integer port) {
20 | return new RqliteImpl(proto, host, port);
21 | }
22 |
23 | public static Rqlite connect(final String config) {
24 | return new RqliteImpl(config);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/dto/ExecuteResults.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.dto;
2 |
3 | import com.google.api.client.json.GenericJson;
4 | import com.google.api.client.util.Key;
5 |
6 | public class ExecuteResults implements GenericResults {
7 | public static class Result extends GenericJson {
8 | @Key
9 | public String error;
10 |
11 | @Key("last_insert_id")
12 | public int lastInsertId;
13 |
14 | @Key("rows_affected")
15 | public int rowsAffected;
16 |
17 | @Key
18 | public float time;
19 | }
20 |
21 | @Key("results")
22 | public Result[] results;
23 |
24 | @Key
25 | public float time;
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/dto/GenericResults.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.dto;
2 |
3 | public interface GenericResults {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/dto/ParameterizedStatement.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.dto;
2 |
3 | import com.google.api.client.json.GenericJson;
4 |
5 | public class ParameterizedStatement extends GenericJson {
6 | public String query;
7 |
8 | public Object[] arguments;
9 |
10 | public ParameterizedStatement(String query, Object[] arguments) {
11 | this.query = query == null ? "" : query;
12 | this.arguments = arguments == null ? new Object[]{} : arguments;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/dto/Pong.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.dto;
2 |
3 | public class Pong implements GenericResults {
4 | public String version;
5 |
6 | public Pong() {
7 | this.version = "unknown";
8 | }
9 |
10 | public Pong(final String version) {
11 | this.version = version;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/dto/QueryResults.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.dto;
2 |
3 | import com.google.api.client.json.GenericJson;
4 | import com.google.api.client.util.Key;
5 |
6 | public class QueryResults implements GenericResults {
7 | public static class Result extends GenericJson {
8 | @Key
9 | public String error;
10 |
11 | @Key
12 | public String[] columns;
13 |
14 | @Key
15 | public String[] types;
16 |
17 | @Key
18 | public Object[][] values;
19 |
20 | @Key
21 | public float time;
22 | }
23 |
24 | @Key
25 | public Result[] results;
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/impl/ExecuteRequest.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.impl;
2 |
3 | import com.google.api.client.http.GenericUrl;
4 | import com.google.api.client.http.HttpRequest;
5 | import com.google.api.client.http.HttpResponse;
6 | import com.rqlite.dto.ExecuteResults;
7 |
8 | import java.io.ByteArrayOutputStream;
9 | import java.io.IOException;
10 |
11 | public class ExecuteRequest extends GenericRequest{
12 |
13 | private HttpRequest httpRequest;
14 |
15 | public ExecuteRequest(HttpRequest request) {
16 | this.httpRequest = request;
17 | }
18 |
19 | public ExecuteResults execute() throws IOException {
20 | HttpResponse response = this.httpRequest.execute();
21 | return response.parseAs(ExecuteResults.class);
22 | }
23 |
24 | public String getUrl() {
25 | return this.httpRequest.getUrl().toString();
26 | }
27 |
28 | public void setUrl(GenericUrl url){
29 | this.httpRequest.setUrl(url);
30 | }
31 |
32 | public String getMethod() {
33 | return this.httpRequest.getRequestMethod();
34 | }
35 |
36 | public String getBody() throws IOException {
37 | ByteArrayOutputStream stream = new ByteArrayOutputStream();
38 | this.httpRequest.getContent().writeTo(stream);
39 | return stream.toString();
40 | }
41 |
42 | public ExecuteRequest enableTransaction(Boolean tx) {
43 | if (tx) {
44 | this.httpRequest.getUrl().put("transaction", tx.toString());
45 | } else {
46 | this.httpRequest.getUrl().remove("transaction");
47 | }
48 | return this;
49 | }
50 |
51 | public ExecuteRequest enableTimings(Boolean tm) {
52 | if (tm) {
53 | this.httpRequest.getUrl().put("timings", tm.toString());
54 | } else {
55 | this.httpRequest.getUrl().remove("timings");
56 | }
57 | return this;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/impl/GenericRequest.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.impl;
2 |
3 | import com.google.api.client.http.GenericUrl;
4 | import com.google.api.client.http.HttpRequest;
5 | import com.rqlite.dto.GenericResults;
6 |
7 | import java.io.IOException;
8 |
9 | abstract class GenericRequest {
10 |
11 | private HttpRequest httpRequest;
12 |
13 | protected abstract GenericResults execute() throws IOException;
14 | public String getUrl() {
15 | return this.httpRequest.getUrl().toString();
16 | }
17 | public void setUrl(GenericUrl url){
18 | this.httpRequest.setUrl(url);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/impl/ParameterizedStatementContent.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.impl;
2 |
3 | import java.io.IOException;
4 | import java.io.OutputStream;
5 |
6 | import com.fasterxml.jackson.core.JsonFactory;
7 | import com.fasterxml.jackson.core.JsonGenerator;
8 | import com.google.api.client.http.AbstractHttpContent;
9 | import com.rqlite.dto.ParameterizedStatement;
10 |
11 | public class ParameterizedStatementContent extends AbstractHttpContent {
12 |
13 | private final ParameterizedStatement[] stmts;
14 | private static final JsonFactory JSON_FACTORY = new JsonFactory();
15 |
16 | protected ParameterizedStatementContent(ParameterizedStatement[] stmts) {
17 | super("application/json");
18 | if (stmts == null) {
19 | stmts = new ParameterizedStatement[]{};
20 | }
21 | this.stmts = stmts;
22 | }
23 |
24 | @Override
25 | public void writeTo(OutputStream out) throws IOException {
26 |
27 | JsonGenerator json = JSON_FACTORY.createGenerator(out);
28 | json.writeStartArray();
29 | for (ParameterizedStatement s : stmts) {
30 | json.writeStartArray();
31 | json.writeString(s.query);
32 | if (s.arguments != null) {
33 | for (Object arg: s.arguments) {
34 | json.writeObject(arg);
35 | }
36 | }
37 | json.writeEndArray();
38 | }
39 | json.writeEndArray();
40 | json.close();
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/impl/PingRequest.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.impl;
2 |
3 | import com.google.api.client.http.HttpHeaders;
4 | import com.google.api.client.http.HttpRequest;
5 | import com.google.api.client.http.HttpResponse;
6 | import com.rqlite.dto.Pong;
7 |
8 | import java.io.IOException;
9 |
10 | public class PingRequest extends GenericRequest{
11 | private HttpRequest httpRequest;
12 |
13 | public PingRequest(HttpRequest request) {
14 | this.httpRequest = request;
15 | }
16 |
17 | public Pong execute() throws IOException {
18 | HttpResponse response = this.httpRequest.execute();
19 |
20 | HttpHeaders headers = response.getHeaders();
21 | String version = headers.getFirstHeaderStringValue("X-Rqlite-Version");
22 |
23 | return new Pong(version);
24 | }
25 |
26 |
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/impl/QueryRequest.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.impl;
2 |
3 | import com.google.api.client.http.GenericUrl;
4 | import com.google.api.client.http.HttpRequest;
5 | import com.google.api.client.http.HttpResponse;
6 | import com.rqlite.Rqlite.ReadConsistencyLevel;
7 | import com.rqlite.dto.QueryResults;
8 |
9 | import java.io.ByteArrayOutputStream;
10 | import java.io.IOException;
11 | import java.io.OutputStream;
12 |
13 | public class QueryRequest extends GenericRequest {
14 |
15 | private HttpRequest httpRequest;
16 |
17 | public QueryRequest(HttpRequest request) {
18 | this.httpRequest = request;
19 | }
20 |
21 | public QueryResults execute() throws IOException {
22 | HttpResponse response = this.httpRequest.execute();
23 | return response.parseAs(QueryResults.class);
24 | }
25 |
26 | public String getUrl() {
27 | return this.httpRequest.getUrl().toString();
28 | }
29 |
30 | public void setUrl(GenericUrl url){
31 | this.httpRequest.setUrl(url);
32 | }
33 |
34 | public String getMethod() {
35 | return this.httpRequest.getRequestMethod();
36 | }
37 |
38 | public String getBody() throws IOException {
39 | ByteArrayOutputStream stream = new ByteArrayOutputStream();
40 | this.httpRequest.getContent().writeTo(stream);
41 | return stream.toString();
42 | }
43 |
44 | public void writeContentTo(OutputStream out) {
45 | return;
46 | }
47 |
48 | public QueryRequest setReadConsistencyLevel(ReadConsistencyLevel lvl) {
49 | this.httpRequest.getUrl().put("level", lvl.toString().toLowerCase());
50 | return this;
51 | }
52 |
53 | public QueryRequest enableTransaction(Boolean tx) {
54 | if (tx) {
55 | this.httpRequest.getUrl().put("transaction", tx.toString());
56 | } else {
57 | this.httpRequest.getUrl().remove("transaction");
58 | }
59 | return this;
60 | }
61 |
62 | public QueryRequest enableTimings(Boolean tm) {
63 | if (tm) {
64 | this.httpRequest.getUrl().put("timings", tm.toString());
65 | } else {
66 | this.httpRequest.getUrl().remove("timings");
67 | }
68 | return this;
69 | }
70 | }
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/impl/RequestFactory.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.impl;
2 |
3 | import java.io.IOException;
4 |
5 | import com.google.api.client.http.GenericUrl;
6 | import com.google.api.client.http.HttpRequest;
7 | import com.google.api.client.http.HttpRequestFactory;
8 | import com.google.api.client.http.HttpRequestInitializer;
9 | import com.google.api.client.http.HttpTransport;
10 | import com.google.api.client.http.javanet.NetHttpTransport;
11 | import com.google.api.client.http.json.JsonHttpContent;
12 | import com.google.api.client.json.JsonFactory;
13 | import com.google.api.client.json.JsonObjectParser;
14 | import com.google.api.client.json.jackson2.JacksonFactory;
15 | import com.rqlite.dto.ParameterizedStatement;
16 |
17 | public class RequestFactory {
18 | static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
19 | static final JsonFactory JSON_FACTORY = new JacksonFactory();
20 |
21 | private HttpRequestFactory requestFactory;
22 |
23 | private String proto;
24 | private String host;
25 | private Integer port;
26 |
27 | private GenericUrl executeUrl;
28 | private GenericUrl queryUrl;
29 | private GenericUrl statusUrl;
30 |
31 | public RequestFactory(final String proto, final String host, final Integer port) {
32 | this.proto = proto;
33 | this.host = host;
34 | this.port = port;
35 |
36 | this.executeUrl = new GenericUrl(String.format("%s://%s:%d/db/execute", this.proto, this.host, this.port));
37 | this.queryUrl = new GenericUrl(String.format("%s://%s:%d/db/query", this.proto, this.host, this.port));
38 | this.statusUrl = new GenericUrl(String.format("%s://%s:%d/status", this.proto, this.host, this.port));
39 |
40 | this.requestFactory = HTTP_TRANSPORT.createRequestFactory(new HttpRequestInitializer() {
41 | public void initialize(HttpRequest request) {
42 | request.setParser(new JsonObjectParser(JSON_FACTORY));
43 | }
44 | });
45 | }
46 |
47 | public ExecuteRequest buildExecuteRequest(String[] stmts) throws IOException {
48 | HttpRequest request = this.buildPostRequest(this.executeUrl, stmts);
49 | return new ExecuteRequest(request);
50 | }
51 |
52 | public ExecuteRequest buildExecuteRequest(ParameterizedStatement[] stmts) throws IOException {
53 | HttpRequest request = this.buildPostRequest(this.executeUrl, stmts);
54 | return new ExecuteRequest(request);
55 | }
56 |
57 | public QueryRequest buildQueryRequest(String[] stmts) throws IOException {
58 | HttpRequest request = this.buildPostRequest(this.queryUrl, stmts);
59 | return new QueryRequest(request);
60 | }
61 |
62 | public QueryRequest buildQueryRequest(ParameterizedStatement[] stmts) throws IOException {
63 | HttpRequest request = this.buildPostRequest(this.queryUrl, stmts);
64 | return new QueryRequest(request);
65 | }
66 |
67 | public PingRequest buildPingRequest() throws IOException {
68 | HttpRequest request = this.requestFactory.buildGetRequest(this.statusUrl);
69 | return new PingRequest(request);
70 | }
71 |
72 | private HttpRequest buildPostRequest(GenericUrl url, String[] stmts) throws IOException {
73 | HttpRequest request = this.requestFactory.buildPostRequest(url, new JsonHttpContent(JSON_FACTORY, stmts));
74 | return request.setParser(new JsonObjectParser(JSON_FACTORY));
75 | }
76 | private HttpRequest buildPostRequest(GenericUrl url, ParameterizedStatement[] stmts) throws IOException {
77 | HttpRequest request = this.requestFactory.buildPostRequest(url, new ParameterizedStatementContent(stmts));
78 | return request.setParser(new JsonObjectParser(JSON_FACTORY));
79 | }
80 |
81 | GenericRequest AdoptRequest(GenericRequest request){
82 | if (request instanceof ExecuteRequest) {request.setUrl(this.executeUrl);}
83 | else if (request instanceof QueryRequest) {request.setUrl(this.queryUrl);}
84 | else {request.setUrl(this.statusUrl);}
85 | return request;
86 | }
87 |
88 | @Override
89 | public String toString() {
90 | return "RequestFactory{" +
91 | "requestFactory=" + requestFactory +
92 | ", proto='" + proto + '\'' +
93 | ", host='" + host + '\'' +
94 | ", port=" + port +
95 | ", executeUrl=" + executeUrl +
96 | ", queryUrl=" + queryUrl +
97 | ", statusUrl=" + statusUrl +
98 | '}';
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/impl/RqliteImpl.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.impl;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.FileNotFoundException;
5 | import java.io.FileReader;
6 | import java.io.IOException;
7 | import java.util.ArrayList;
8 | import java.util.HashMap;
9 | import java.util.List;
10 | import java.util.Map;
11 |
12 | import com.google.api.client.http.HttpResponseException;
13 | import com.google.api.client.http.HttpTransport;
14 | import com.google.api.client.http.javanet.NetHttpTransport;
15 | import com.google.api.client.json.JsonFactory;
16 | import com.google.api.client.json.jackson2.JacksonFactory;
17 | import com.rqlite.NodeUnavailableException;
18 | import com.rqlite.Rqlite;
19 | import com.rqlite.dto.ExecuteResults;
20 | import com.rqlite.dto.GenericResults;
21 | import com.rqlite.dto.ParameterizedStatement;
22 | import com.rqlite.dto.Pong;
23 | import com.rqlite.dto.QueryResults;
24 |
25 | public class RqliteImpl implements Rqlite {
26 |
27 | static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
28 | static final JsonFactory JSON_FACTORY = new JacksonFactory();
29 |
30 | private RequestFactory requestFactory;
31 |
32 | private List peers; // only initialized if evaluating a config file
33 | private int timeoutDelay = 8000;
34 |
35 | Map nodeRequestFactoryMap = new HashMap<>();
36 |
37 | public RqliteImpl(final String proto, final String host, final Integer port) {
38 | this.requestFactory = new RequestFactory(proto, host, port);
39 | }
40 |
41 | public RqliteImpl(final String configPath) {
42 | loadPeersFromConfig(configPath);
43 | this.requestFactory = new RequestFactory(peers.get(0).proto, peers.get(0).host, peers.get(0).port);
44 | }
45 |
46 | public void setTimeoutDelay(int delay) {
47 | this.timeoutDelay = delay;
48 | }
49 |
50 | private void loadPeersFromConfig(String configPath){
51 | this.peers = new ArrayList<>();
52 | try (BufferedReader br = new BufferedReader(new FileReader(configPath))) {
53 | String line;
54 | while ((line = br.readLine()) != null) {
55 | String[] values = line.split(",");
56 | peers.add(new RqliteNode(values[0], values[1], Integer.valueOf(values[2])));
57 | }
58 | } catch(FileNotFoundException e) {
59 | e.printStackTrace();
60 | } catch (IOException e) {
61 | e.printStackTrace();
62 | }
63 | }
64 |
65 | private GenericResults tryOtherPeers(GenericRequest request, String[] stmts) throws NodeUnavailableException {
66 | // Cycle through the list of nodes in the config file.
67 | long end = System.currentTimeMillis() + timeoutDelay;
68 | if (peers != null) {
69 | while (System.currentTimeMillis() < end) {
70 | for (RqliteNode node : this.peers) {
71 | try {
72 | if (nodeRequestFactoryMap.containsKey(node)) {
73 | requestFactory = nodeRequestFactoryMap.get(node);
74 | } else {
75 | requestFactory = new RequestFactory(node.proto, node.host, node.port);
76 | nodeRequestFactoryMap.put(node, requestFactory);
77 | }
78 | GenericRequest r = requestFactory.AdoptRequest(request);
79 | GenericResults results = r.execute();
80 | return results;
81 | } catch (IOException e) {
82 | }
83 | }
84 | // pause to avoid churning
85 | try {
86 | Thread.sleep(100);
87 | } catch (InterruptedException e) {
88 | }
89 | }
90 | }
91 | throw new NodeUnavailableException("Could not connect to rqlite node. Please check that the node is online and that your config files point to the correct address.");
92 | }
93 |
94 | private GenericResults tryOtherPeers(GenericRequest request, ParameterizedStatement[] stmts) throws NodeUnavailableException {
95 | // Cycle through the list of nodes in the config file.
96 | long end = System.currentTimeMillis() + timeoutDelay;
97 | if (peers != null) {
98 | while (System.currentTimeMillis() < end) {
99 | for (RqliteNode node : this.peers) {
100 | try {
101 | if (nodeRequestFactoryMap.containsKey(node)) {
102 | requestFactory = nodeRequestFactoryMap.get(node);
103 | } else {
104 | requestFactory = new RequestFactory(node.proto, node.host, node.port);
105 | nodeRequestFactoryMap.put(node, requestFactory);
106 | }
107 | GenericRequest r = requestFactory.AdoptRequest(request);
108 | GenericResults results = r.execute();
109 | return results;
110 | } catch (IOException e) {
111 | }
112 | }
113 | // pause to avoid churning
114 | try {
115 | Thread.sleep(100);
116 | } catch (InterruptedException e) {
117 | }
118 | }
119 | }
120 | throw new NodeUnavailableException("Could not connect to rqlite node. Please check that the node is online and that your config files point to the correct address.");
121 | }
122 |
123 | public QueryResults Query(String[] stmts, boolean tx, ReadConsistencyLevel lvl) throws NodeUnavailableException {
124 | QueryRequest request;
125 |
126 | try {
127 | request = this.requestFactory.buildQueryRequest(stmts);
128 | } catch (IOException e1) {
129 | // TODO Auto-generated catch block
130 | e1.printStackTrace();
131 | return null;
132 | }
133 | request.enableTransaction(tx).setReadConsistencyLevel(lvl);
134 |
135 | try {
136 | return request.execute();
137 | } catch (HttpResponseException responseException) {
138 | return (QueryResults) this.tryOtherPeers(request, stmts);
139 | } catch (IOException e) {
140 | // TODO Auto-generated catch block
141 | return (QueryResults) this.tryOtherPeers(request, stmts);
142 | }
143 | }
144 | @Override
145 | public QueryResults Query(ParameterizedStatement[] stmts, boolean tx, ReadConsistencyLevel lvl) throws NodeUnavailableException {
146 | QueryRequest request;
147 |
148 | try {
149 | request = this.requestFactory.buildQueryRequest(stmts);
150 | } catch (IOException e1) {
151 | // TODO Auto-generated catch block
152 | e1.printStackTrace();
153 | return null;
154 | }
155 | request.enableTransaction(tx).setReadConsistencyLevel(lvl);
156 |
157 | try {
158 | return request.execute();
159 | } catch (HttpResponseException responseException) {
160 | return (QueryResults) this.tryOtherPeers(request, stmts);
161 | } catch (IOException e) {
162 | // TODO Auto-generated catch block
163 | return (QueryResults) this.tryOtherPeers(request, stmts);
164 | }
165 | }
166 |
167 | public QueryResults Query(String s, ReadConsistencyLevel lvl) throws NodeUnavailableException {
168 | return this.Query(new String[] { s }, false, lvl);
169 | }
170 |
171 | @Override
172 | public QueryResults Query(ParameterizedStatement q, ReadConsistencyLevel lvl) throws NodeUnavailableException {
173 | return this.Query(new ParameterizedStatement[] { q }, false, lvl);
174 | }
175 |
176 | public ExecuteResults Execute(String[] stmts, boolean tx) throws NodeUnavailableException {
177 | ExecuteRequest request;
178 | try {
179 | request = this.requestFactory.buildExecuteRequest(stmts);
180 | } catch (IOException e1) {
181 | // TODO Auto-generated catch block
182 | e1.printStackTrace();
183 | return null;
184 | }
185 | request.enableTransaction(tx);
186 |
187 | try {
188 | return request.execute();
189 | } catch (HttpResponseException responseException) {
190 | return (ExecuteResults) this.tryOtherPeers(request, stmts);
191 | } catch (IOException e) {
192 | // TODO Auto-generated catch block
193 | return (ExecuteResults) this.tryOtherPeers(request, stmts);
194 | }
195 | }
196 |
197 | @Override
198 | public ExecuteResults Execute(ParameterizedStatement[] stmts, boolean tx) throws NodeUnavailableException {
199 | ExecuteRequest request;
200 | try {
201 | request = this.requestFactory.buildExecuteRequest(stmts);
202 | } catch (IOException e1) {
203 | // TODO Auto-generated catch block
204 | e1.printStackTrace();
205 | return null;
206 | }
207 | request.enableTransaction(tx);
208 |
209 | try {
210 | return request.execute();
211 | } catch (HttpResponseException responseException) {
212 | return (ExecuteResults) this.tryOtherPeers(request, stmts);
213 | } catch (IOException e) {
214 | // TODO Auto-generated catch block
215 | return (ExecuteResults) this.tryOtherPeers(request, stmts);
216 | }
217 | }
218 |
219 | public ExecuteResults Execute(String s) throws NodeUnavailableException {
220 | return this.Execute(new String[] { s }, false);
221 | }
222 |
223 | @Override
224 | public ExecuteResults Execute(ParameterizedStatement q) throws NodeUnavailableException {
225 | return this.Execute(new ParameterizedStatement[]{ q }, false);
226 | }
227 |
228 | public Pong Ping() {
229 | try {
230 | return this.requestFactory.buildPingRequest().execute();
231 | } catch (IOException e) {
232 | // TODO Auto-generated catch block
233 | e.printStackTrace();
234 | return null;
235 | }
236 | }
237 | }
238 |
--------------------------------------------------------------------------------
/src/main/java/com/rqlite/impl/RqliteNode.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.impl;
2 |
3 | public class RqliteNode {
4 | public String proto;
5 | public String host;
6 | public Integer port;
7 |
8 | public RqliteNode(String proto, String host, Integer port){
9 | this.proto = proto;
10 | this.host = host;
11 | this.port = port;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/test/java/com/rqlite/RqliteClientTest.java:
--------------------------------------------------------------------------------
1 | package com.rqlite;
2 |
3 | import java.math.BigDecimal;
4 |
5 | import org.junit.After;
6 | import org.junit.Assert;
7 | import org.junit.Before;
8 | import org.junit.Test;
9 |
10 | import com.rqlite.dto.ExecuteResults;
11 | import com.rqlite.dto.ParameterizedStatement;
12 | import com.rqlite.dto.QueryResults;
13 |
14 | public class RqliteClientTest {
15 |
16 | public Rqlite rqlite;
17 |
18 | @Before
19 | public void setup(){
20 | rqlite = RqliteFactory.connect("http", "localhost", 4001);
21 | }
22 |
23 | @Test
24 | public void testRqliteClientSingle() throws NodeUnavailableException {
25 | ExecuteResults results = null;
26 | QueryResults rows = null;
27 |
28 | try {
29 |
30 | results = rqlite.Execute("CREATE TABLE foo (id integer not null primary key, name text)");
31 | Assert.assertNotNull(results);
32 | Assert.assertEquals(1, results.results.length);
33 |
34 | results = rqlite.Execute("INSERT INTO foo(name) VALUES(\"fiona\")");
35 | Assert.assertNotNull(results);
36 | Assert.assertEquals(1, results.results.length);
37 | Assert.assertEquals(1, results.results[0].lastInsertId);
38 |
39 | rows = rqlite.Query("SELECT * FROM foo", Rqlite.ReadConsistencyLevel.WEAK);
40 | Assert.assertNotNull(rows);
41 | Assert.assertEquals(1, rows.results.length);
42 | Assert.assertArrayEquals(new String[]{"id", "name"}, rows.results[0].columns);
43 | Assert.assertArrayEquals(new String[]{"integer", "text"}, rows.results[0].types);
44 | Assert.assertEquals(1, rows.results[0].values.length);
45 | Assert.assertArrayEquals(new Object[]{new BigDecimal(1), "fiona"}, rows.results[0].values[0]);
46 |
47 | results = rqlite.Execute("CREATE TABLE secret_agents (id integer not null primary key, name text, secret text)");
48 | Assert.assertNotNull(results);
49 | Assert.assertEquals(1, results.results.length);
50 |
51 | results = rqlite.Execute(new ParameterizedStatement("INSERT INTO secret_agents(id, name, secret) VALUES(?, ?, ?)", new Object[]{7, "James Bond", "not-a-secret"}));
52 | Assert.assertNotNull(results);
53 | Assert.assertEquals(1, results.results.length);
54 | Assert.assertNull(results.results[0].error);
55 | Assert.assertEquals(7, results.results[0].lastInsertId);
56 | } catch (NodeUnavailableException e) {
57 | Assert.fail("Failed because rqlite-java could not connect to the node.");
58 | }
59 | }
60 |
61 | @Test
62 | public void testRqliteClientMulti() {
63 | ExecuteResults results = null;
64 | QueryResults rows = null;
65 |
66 | try {
67 | results = rqlite.Execute("CREATE TABLE bar (id integer not null primary key, name text)");
68 | Assert.assertNotNull(results);
69 | Assert.assertEquals(1, results.results.length);
70 |
71 | String[] s = {"INSERT INTO bar(name) VALUES(\"fiona\")", "INSERT INTO bar(name) VALUES(\"declan\")"};
72 | results = rqlite.Execute(s, false);
73 | Assert.assertNotNull(results);
74 | Assert.assertEquals(2, results.results.length);
75 | Assert.assertEquals(1, results.results[0].lastInsertId);
76 | Assert.assertEquals(2, results.results[1].lastInsertId);
77 |
78 | String[] q = {"SELECT * FROM bar", "SELECT name FROM bar"};
79 | rows = rqlite.Query(q, false, Rqlite.ReadConsistencyLevel.WEAK);
80 | Assert.assertNotNull(rows);
81 | Assert.assertNotNull(rows);
82 | Assert.assertEquals(2, rows.results.length);
83 |
84 | // SELECT * FROM bar
85 | Assert.assertArrayEquals(new String[]{"id", "name"}, rows.results[0].columns);
86 | Assert.assertArrayEquals(new String[]{"integer", "text"}, rows.results[0].types);
87 | Assert.assertEquals(2, rows.results[0].values.length);
88 | Assert.assertArrayEquals(new Object[]{new BigDecimal(1), "fiona"}, rows.results[0].values[0]);
89 | Assert.assertArrayEquals(new Object[]{new BigDecimal(2), "declan"}, rows.results[0].values[1]);
90 |
91 | // SELECT name FROM bar
92 | Assert.assertArrayEquals(new String[]{"name"}, rows.results[1].columns);
93 | Assert.assertArrayEquals(new String[]{"text"}, rows.results[1].types);
94 | Assert.assertEquals(2, rows.results[1].values.length);
95 | Assert.assertArrayEquals(new Object[]{"fiona"}, rows.results[1].values[0]);
96 | Assert.assertArrayEquals(new Object[]{"declan"}, rows.results[1].values[1]);
97 | } catch (NodeUnavailableException e) {
98 | Assert.fail("Failed because rqlite-java could not connect to the node.");
99 | }
100 | }
101 |
102 | @Test
103 | public void testRqliteClientSyntax() {
104 | ExecuteResults results = null;
105 | QueryResults rows = null;
106 | try {
107 | results = rqlite.Execute("nonsense");
108 | Assert.assertNotNull(results);
109 | Assert.assertEquals(1, results.results.length);
110 | Assert.assertEquals(0, results.results[0].rowsAffected);
111 | Assert.assertEquals("near \"nonsense\": syntax error", results.results[0].error);
112 |
113 | rows = rqlite.Query("more nonsense", Rqlite.ReadConsistencyLevel.WEAK);
114 | Assert.assertNotNull(rows);
115 | Assert.assertEquals(1, rows.results.length);
116 | Assert.assertEquals("near \"more\": syntax error", rows.results[0].error);
117 | } catch (NodeUnavailableException e) {
118 | Assert.fail("Failed because rqlite-java could not connect to the node.");
119 | }
120 | }
121 |
122 | @After
123 | public void after() throws Exception {
124 | Rqlite rqlite = RqliteFactory.connect("http", "localhost", 4001);
125 | rqlite.Execute("DROP TABLE foo");
126 | rqlite.Execute("DROP TABLE bar");
127 | rqlite.Execute("DROP TABLE secret_agents");
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/test/java/com/rqlite/RqliteFactoryTest.java:
--------------------------------------------------------------------------------
1 | package com.rqlite;
2 |
3 | import java.util.Map;
4 |
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | import com.rqlite.dto.Pong;
9 |
10 | public class RqliteFactoryTest {
11 |
12 | @Test
13 | public void testCreateRqliteInstance() {
14 | Rqlite rqlite = RqliteFactory.connect("http", "localhost", 4001);
15 | Assert.assertNotNull(rqlite);
16 | }
17 |
18 | @Test
19 | public void testCreateRqliteInstancePing() {
20 | Rqlite rqlite = RqliteFactory.connect("http", "localhost", 4001);
21 | Pong pong = rqlite.Ping();
22 | Assert.assertEquals(getRqliteVersion(), pong.version);
23 | }
24 |
25 | private String getRqliteVersion() {
26 | Map getenv = System.getenv();
27 | if (getenv.containsKey("RQLITE_VERSION")) {
28 | return getenv.get("RQLITE_VERSION");
29 | }
30 | return "unknown";
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/com/rqlite/RqliteFailoverTest.java:
--------------------------------------------------------------------------------
1 | package com.rqlite;
2 |
3 | import com.rqlite.dto.ExecuteResults;
4 | import com.rqlite.dto.QueryResults;
5 | import org.junit.After;
6 | import org.junit.Assert;
7 | import org.junit.Before;
8 | import org.junit.Test;
9 |
10 | import java.io.IOException;
11 | import java.math.BigDecimal;
12 | import java.nio.file.Files;
13 | import java.nio.file.Paths;
14 | import java.util.UUID;
15 |
16 | public class RqliteFailoverTest {
17 | String rqlitePath;
18 | Process node2;
19 | Process node3;
20 | Process node4;
21 |
22 | @Before
23 | public void setUp() throws IOException{
24 | // rqlitePath.config should contain one line with a path to the installation directory of Rqlite
25 | try {
26 | rqlitePath = Files.readAllLines(Paths.get("resources/rqlitePath.config")).get(0);
27 | } catch (IOException e){
28 | System.err.println(e);
29 | }
30 |
31 | //Create 3 nodes
32 | ProcessBuilder pb1 = new ProcessBuilder(rqlitePath + "/./rqlited",
33 | "-node-id", "node.2",
34 | "-http-addr", "localhost:4007",
35 | "-raft-addr", "localhost:4008",
36 | "target/rqlitenodes/node2." + UUID.randomUUID()) ;
37 | node2 = pb1.start();
38 |
39 | try {
40 | Thread.sleep(2000); //Give this node 2 seconds to establish itself as leader
41 | } catch (InterruptedException e) { }
42 |
43 | ProcessBuilder pb2 = new ProcessBuilder(rqlitePath + "/./rqlited",
44 | "-node-id", "node.3",
45 | "-http-addr", "localhost:4003",
46 | "-raft-addr", "localhost:4004",
47 | "-join", "localhost:4007",
48 | "target/rqlitenodes/node3." + UUID.randomUUID());
49 | node3 = pb2.start();
50 |
51 | ProcessBuilder pb3 = new ProcessBuilder(rqlitePath + "/./rqlited",
52 | "-node-id", "node.4",
53 | "-http-addr", "localhost:4005",
54 | "-raft-addr", "localhost:4006",
55 | "-join", "localhost:4007",
56 | "target/rqlitenodes/node4." + UUID.randomUUID());
57 | node4 = pb3.start();
58 | }
59 |
60 | @Test
61 | public void testRqliteFailover() throws IOException {
62 | //connect to node.2 with config file
63 | Rqlite rqlite = RqliteFactory.connect("resources/FailoverTest.nodehosts.config");
64 | ExecuteResults results = null;
65 | QueryResults rows = null;
66 |
67 | try {
68 | results = rqlite.Execute("CREATE TABLE baz (id integer not null primary key, name text)");
69 | Assert.assertNotNull(results);
70 | Assert.assertEquals(1, results.results.length);
71 |
72 | //Connect to node.2 without config file
73 | Rqlite rqlite2 = RqliteFactory.connect("http", "localhost", 4007);
74 |
75 | //Kill leader node.2
76 | node2.destroy();
77 |
78 | //see if rqlite with config file has recovered
79 | results = rqlite.Execute("INSERT INTO baz(name) VALUES(\"fiona\")");
80 | Assert.assertNotNull(results);
81 | Assert.assertEquals(1, results.results.length);
82 | Assert.assertEquals(1, results.results[0].lastInsertId);
83 |
84 | rows = rqlite.Query("SELECT * FROM baz", Rqlite.ReadConsistencyLevel.WEAK);
85 | Assert.assertNotNull(rows);
86 | Assert.assertEquals(1, rows.results.length);
87 | Assert.assertArrayEquals(new String[]{"id", "name"}, rows.results[0].columns);
88 | Assert.assertArrayEquals(new String[]{"integer", "text"}, rows.results[0].types);
89 | Assert.assertEquals(1, rows.results[0].values.length);
90 | Assert.assertArrayEquals(new Object[]{new BigDecimal(1), "fiona"}, rows.results[0].values[0]);
91 |
92 | //rqlite without config file should fail
93 | try {
94 | rows = rqlite2.Query("SELECT * FROM baz", Rqlite.ReadConsistencyLevel.WEAK);
95 | Assert.fail("Expected NodeUnavailableException was not thrown.");
96 | } catch (NodeUnavailableException e) {}
97 |
98 | } catch (Exception e) {
99 | Assert.fail("Failed due to an unexpected exception.\n" + e.getMessage());
100 | }
101 | }
102 |
103 | @After
104 | public void tearDown(){
105 | node3.destroy();
106 | node4.destroy();
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/test/java/com/rqlite/impl/RequestFactoryTest.java:
--------------------------------------------------------------------------------
1 | package com.rqlite.impl;
2 |
3 | import java.io.IOException;
4 |
5 | import org.junit.Assert;
6 | import org.junit.Test;
7 |
8 | import com.rqlite.Rqlite;
9 |
10 | public class RequestFactoryTest {
11 | @Test
12 | public void testRequestFactoryQuery() throws IOException {
13 | RequestFactory factory = new RequestFactory("http", "localhost", 4001);
14 | QueryRequest request = factory.buildQueryRequest(new String[] {});
15 | Assert.assertEquals("http://localhost:4001/db/query", request.getUrl());
16 | Assert.assertEquals("POST", request.getMethod());
17 | Assert.assertEquals("[]", request.getBody());
18 |
19 | request.enableTransaction(true);
20 | Assert.assertEquals("http://localhost:4001/db/query?transaction=true", request.getUrl());
21 |
22 | request.enableTransaction(false);
23 | Assert.assertEquals("http://localhost:4001/db/query", request.getUrl());
24 |
25 | request.setReadConsistencyLevel(Rqlite.ReadConsistencyLevel.STRONG);
26 | Assert.assertEquals("http://localhost:4001/db/query?level=strong", request.getUrl());
27 |
28 | request.setReadConsistencyLevel(Rqlite.ReadConsistencyLevel.WEAK);
29 | Assert.assertEquals("http://localhost:4001/db/query?level=weak", request.getUrl());
30 |
31 | request.setReadConsistencyLevel(Rqlite.ReadConsistencyLevel.NONE);
32 | Assert.assertEquals("http://localhost:4001/db/query?level=none", request.getUrl());
33 | }
34 |
35 | @Test
36 | public void testRequestFactorQueryStatement() throws IOException {
37 | RequestFactory factory = new RequestFactory("http", "localhost", 4001);
38 | QueryRequest request = factory.buildQueryRequest(new String[] { "SELECT * FROM foo" });
39 | Assert.assertEquals("http://localhost:4001/db/query", request.getUrl());
40 | Assert.assertEquals("POST", request.getMethod());
41 | Assert.assertEquals("[\"SELECT * FROM foo\"]", request.getBody());
42 | }
43 |
44 | @Test
45 | public void testRequestFactorQueryStatementMulti() throws IOException {
46 | RequestFactory factory = new RequestFactory("http", "localhost", 4001);
47 | QueryRequest request = factory.buildQueryRequest(new String[] { "SELECT * FROM foo", "SELECT * FROM bar" });
48 | Assert.assertEquals("http://localhost:4001/db/query", request.getUrl());
49 | Assert.assertEquals("POST", request.getMethod());
50 | Assert.assertEquals("[\"SELECT * FROM foo\",\"SELECT * FROM bar\"]", request.getBody());
51 | }
52 |
53 | @Test
54 | public void testRequestFactorExecute() throws IOException {
55 | RequestFactory factory = new RequestFactory("http", "localhost", 4001);
56 | ExecuteRequest request = factory.buildExecuteRequest(new String[] {});
57 | Assert.assertEquals("http://localhost:4001/db/execute", request.getUrl());
58 | Assert.assertEquals("POST", request.getMethod());
59 | Assert.assertEquals("[]", request.getBody());
60 |
61 | request.enableTransaction(true);
62 | Assert.assertEquals("http://localhost:4001/db/execute?transaction=true", request.getUrl());
63 |
64 | request.enableTransaction(false);
65 | Assert.assertEquals("http://localhost:4001/db/execute", request.getUrl());
66 | }
67 |
68 | @Test
69 | public void testRequestFactorExecuteStatementMulti() throws IOException {
70 | RequestFactory factory = new RequestFactory("http", "localhost", 4001);
71 | ExecuteRequest request = factory.buildExecuteRequest(
72 | new String[] { "INSERT INTO foo(name) VALUES(1)", "INSERT INTO foo(name) VALUES(2)" });
73 | Assert.assertEquals("http://localhost:4001/db/execute", request.getUrl());
74 | Assert.assertEquals("POST", request.getMethod());
75 | Assert.assertEquals("[\"INSERT INTO foo(name) VALUES(1)\",\"INSERT INTO foo(name) VALUES(2)\"]",
76 | request.getBody());
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------