couchbasequerydslcouchbase-java-api

Get the String sql from a Couchbase N1qlQuery DSL?


After building a query object like in this stack overflow answer or examples in couchbase java n1ql queries docs can we get the string query before sending it to the server? I do not want to send it to the server. Merely want to build it with the DSL, then get the string of the complete query with parameters in place, what would have gone to the server, and process it in another way.


Solution

  • A Statement can be converted to a String just by calling toString():

    import com.couchbase.client.java.document.json.JsonObject;
    import com.couchbase.client.java.query.N1qlQuery;
    import com.couchbase.client.java.query.Statement;
    
    import static com.couchbase.client.java.query.Select.select;
    import static com.couchbase.client.java.query.dsl.Expression.i;
    import static com.couchbase.client.java.query.dsl.Expression.path;
    import static com.couchbase.client.java.query.dsl.Expression.s;
    import static com.couchbase.client.java.query.dsl.Expression.x;
    
    Statement statement = select(path(i("travel-sample"), "*"))
        .from(i("travel-sample"))
        .where(x("name").eq(x("$airline_param"))
            .and(x("type").eq(s("airline"))));
    
    System.out.println(statement);
    

    OUTPUT:

    SELECT `travel-sample`.* FROM `travel-sample` WHERE name = $airline_param AND type = "airline"
    

    As you can see, this does not do any parameter replacement. Arguments are sent to the server separately from the statement. If you want to see what gets sent to the server, you can call N1qlQuery.n1ql():

    JsonObject args = JsonObject.create().put("$airline_param", "FooFliers");
    N1qlQuery q = N1qlQuery.parameterized(statement, args);
    
    JsonObject statementAndArgs = q.n1ql(); 
    System.out.println(statementAndArgs);
    

    OUTPUT (prettified):

    {
      "statement": "SELECT `travel-sample`.* FROM `travel-sample` WHERE name = $airline_param AND type = \"airline\"",
      "$airline_param": "FooFliers"
    }
    

    If you need the arguments to be inlined then you'll need to do that part yourself, being extra careful to escape string arguments properly.