pietermartin / sqlg

TinkerPop graph over sql
MIT License
246 stars 51 forks source link

Not able to execute userdefined query from sqlg #473

Closed ninadmahalle1994 closed 1 year ago

ninadmahalle1994 commented 1 year ago

Hi Pieter, Hope you are doing well. We are using SQLG in one of the project, it is working very well for us. however we are having a custom requirement were we want our users to write there own Gremlin/SQLG query and execute it. I looked around the web but didn't found any solid solution on it. I want to know if this is possible using SQLG ? It will be great help to me if you suggest solution.

Thanks in advance.

pietermartin commented 1 year ago

Hi,

Can give more details regarding what you have in mind with "Gremlin/SQLG query and execute it"?

Thanks

ninadmahalle1994 commented 1 year ago

Hi, I want to send query as string to api directly and return a traversal result.

ninadmahalle1994 commented 1 year ago

I want to execute the sqlg query using gremlin executor in java. I tried using it but am not able to get it.

ninadmahalle1994 commented 1 year ago

sorry for late reply. We are able to create vertex and links , the user should be able to send plain text as query and should return a traversal result form the created graph. i tried using gremlin executor but we are not able to execute the query. i tried searching , but did not get any solid solution.

For example- "g.V().count()", in the same way if i send a query as text for traversal the api should return graph traversal result.

pietermartin commented 1 year ago

Hi, I use groovy to execute gremlin strings in java. BTW, I am using groovy 3 and exclude the groovy that comes from TinkerPop. Below is a bit of code I used before to test groovy performance.

    @Test
    public void testGroovy() {
        Vertex v1 = this.sqlgGraph.addVertex(T.label, "Person");
        GroovyShell shell = new GroovyShell();
        Map<String, Object> bindings = new HashMap<>();
        bindings.put("g", this.sqlgGraph.traversal());
        Binding groovyBinding = new Binding(bindings);
        Script script1 = shell.parse("g.V().hasLabel('Person').next()");
        script1.setBinding(groovyBinding);

        StopWatch stopWatch =StopWatch.createStarted();
        for (int i = 0; i < 10; i++) {
            Object v = script1.run();
            Assert.assertEquals(v1, v);
            stopWatch.stop();
            LOGGER.info("time: " + stopWatch.toString());
            stopWatch.reset();
            stopWatch.start();
        }
        stopWatch.stop();
        LOGGER.debug("time: " + stopWatch.toString());
    }

Here is some more code I use to interpret the result.

    public String executeGroovyAsString(DATABASE database, String groovy) throws Exception {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Object result = eval(database, groovy);

        Iterator<?> tempIterator = Collections.emptyIterator();
        StringBuilder sb = new StringBuilder();

        while (true) {
            if (tempIterator.hasNext()) {
                while (tempIterator.hasNext()) {
                    final Object object = tempIterator.next();
                    sb.append(((null == object) ? null : object.toString()));
                    sb.append("\n");
                }
                break;
            } else {
                if (result instanceof Iterator) {
                    tempIterator = (Iterator<?>) result;
                    if (!tempIterator.hasNext()) break;
                } else if (result instanceof Iterable) {
                    tempIterator = ((Iterable<?>) result).iterator();
                    if (!tempIterator.hasNext()) break;
                } else if (result instanceof Object[]) {
                    tempIterator = new ArrayIterator((Object[]) result);
                    if (!tempIterator.hasNext()) break;
                } else if (result instanceof Map) {
                    tempIterator = ((Map<?, ?>) result).entrySet().iterator();
                    if (!tempIterator.hasNext()) break;
                } else {
                    sb.append(((null == result) ? null : result.toString()));
                    break;
                }
            }
        }

        stopWatch.stop();
        sb.append("Time to execute query = ");
        sb.append(stopWatch);
        return sb.toString();
    }

The DATABASE enum here just refers to different graphs.

Hope it helps.

ninadmahalle1994 commented 1 year ago

hello pieter, Thank you so much for the code it started working, I was facing some issues with dependencies. your code helped in solving the issues.