Skip to content

Commit

Permalink
feat: adjust panic to Java Exception (#1971)
Browse files Browse the repository at this point in the history
* build: update to version 0.5.2

* feat: add Exception for method signature

* chore: add Exception for test method

* feat: adjust panic to Java Exception and add format method

* chore: use implicit return

* test: add compileWithError() to test compile with error

* feat: add dialect, format and signature parameters for toSql method

* chore: update toSql method signature

* lint: code polishing reported by clippy

* chore: code format

* docs: adjust signature for toSQL()

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* docs: format

* chore: introduce target dialect from https://github.com/PRQL/prql/blob/main/book/src/language-features/target.md

* chore: rename dialect to target

* Use target rather than dialect

* lint

* docs: add javadoc for toSql()

---------

Co-authored-by: Maximilian Roos <5635139+max-sixty@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Roos <m@maxroos.com>
  • Loading branch information
4 people authored Mar 1, 2023
1 parent b666fb6 commit 4b4a810
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 19 deletions.
4 changes: 2 additions & 2 deletions prql-java/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ We implement Rust bindings to Java with
[JNI](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/).

First, define a native method --
`public static native String toSql(String query)` for PrqlCompiler, `toJson` is
same.
`public static native String toSql(String query, String target, boolean format, boolean signature)`
for PrqlCompiler, `toJson` is same.

And then implement it in Rust with this
[crate](https://docs.rs/jni/latest/jni/).
Expand Down
2 changes: 1 addition & 1 deletion prql-java/java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.prqllang</groupId>
<artifactId>prql-java</artifactId>
<version>0.2.1</version>
<version>0.5.2</version>

<name>${project.groupId}:${project.artifactId}</name>
<description>prql-compiler api for java</description>
Expand Down
15 changes: 13 additions & 2 deletions prql-java/java/src/main/java/org/prql/prql4j/PrqlCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,19 @@
import java.io.IOException;

public class PrqlCompiler {
public static native String toSql(String query);
public static native String toJson(String query);

/**
* compile PRQL to SQL
* @param query PRQL query
* @param target target dialect, such as sql.mysql etc. Please refer <a href="https://github.com/PRQL/prql/blob/main/book/src/language-features/target.md">PRQL Target and Version</a>
* @param format format SQL or not
* @param signature comment signature or not
* @return SQL
* @throws Exception PRQL compile exception
*/
public static native String toSql(String query, String target, boolean format, boolean signature) throws Exception;
public static native String toJson(String query) throws Exception;
public static native String format(String query) throws Exception;

static {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

public class PrqlCompilerTest {
@Test
public void compile() {
String found = PrqlCompiler.toSql("from table");
public void compile() throws Exception {
String found = PrqlCompiler.toSql("from table", "sql.mysql", true, true);

// remove signature
found = found.substring(0, found.indexOf("\n\n--"));
Expand All @@ -16,4 +16,9 @@ public void compile() {
" table";
assert expected.equalsIgnoreCase(found);
}

@Test(expected = Exception.class)
public void compileWithError() throws Exception {
PrqlCompiler.toSql("from table | filter id >> 1", "sql.mysql", true, true);
}
}
61 changes: 49 additions & 12 deletions prql-java/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,50 @@
use jni::objects::{JClass, JString};
use jni::sys::jstring;
use jni::sys::{jboolean, jstring};
use jni::JNIEnv;
use prql_compiler::{json, prql_to_pl, Options};
use prql_compiler::{json, pl_to_prql, prql_to_pl, ErrorMessages, Options, Target};
use std::str::FromStr;

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn Java_org_prql_prql4j_PrqlCompiler_toSql(
env: JNIEnv,
_class: JClass,
query: JString,
target: JString,
format: jboolean,
signature: jboolean,
) -> jstring {
let prql_query: String = env
.get_string(query)
.expect("Couldn't get java string!")
.into();
let rs_sql_str: String = prql_compiler::compile(&prql_query, &Options::default())
.expect("Couldn't compile query to prql!");
env.new_string(rs_sql_str)
.expect("Couldn't create java string!")
.into_raw()
let target_str: String = env
.get_string(target)
.expect("Couldn't get java string")
.into();
let prql_dialect: Target = Target::from_str(&target_str).unwrap_or(Target::Sql(None));
let opt = Options {
format: format != 0,
target: prql_dialect,
signature_comment: signature != 0,
};
let result = prql_compiler::compile(&prql_query, &opt);
java_string_with_exception(result, &env)
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn Java_org_prql_prql4j_PrqlCompiler_format(
env: JNIEnv,
_class: JClass,
query: JString,
) -> jstring {
let prql_query: String = env
.get_string(query)
.expect("Couldn't get java string!")
.into();
let result = prql_to_pl(&prql_query).and_then(pl_to_prql);
java_string_with_exception(result, &env)
}

#[no_mangle]
Expand All @@ -32,9 +58,20 @@ pub extern "system" fn Java_org_prql_prql4j_PrqlCompiler_toJson(
.get_string(query)
.expect("Couldn't get java string!")
.into();
let rs_json_str: String = { prql_to_pl(&prql_query).and_then(json::from_pl) }
.expect("Couldn't get json from prql query!");
env.new_string(rs_json_str)
.expect("Couldn't create java string!")
.into_raw()
let result = prql_to_pl(&prql_query).and_then(json::from_pl);
java_string_with_exception(result, &env)
}

fn java_string_with_exception(result: Result<String, ErrorMessages>, env: &JNIEnv) -> jstring {
if let Ok(text) = result {
env.new_string(text)
.expect("Couldn't create java string!")
.into_raw()
} else {
let exception = env.find_class("java/lang/Exception").unwrap();
if let Err(e) = env.throw_new(exception, result.err().unwrap().to_string()) {
println!("Error throwing exception: {:?}", e);
}
std::ptr::null_mut() as jstring
}
}

0 comments on commit 4b4a810

Please sign in to comment.