Skip to content

bowbahdoe/josql

Repository files navigation

JoSQL

This is a repackaging and light touching up of the JoSQL Java library, originally released by Gary Bently for Java 1.4 in 2005.

(If anyone has more info on the original author or context on the project I'd love to add it)

Usage

<depencency>
  <groupId>dev.mccue</groupId>
  <artifactId>josql</artifactId>
  <version>2023.08.05</version>
</depencency>
package example;

import dev.mccue.josql.Query;
import dev.mccue.josql.QueryExecutionException;
import dev.mccue.josql.QueryParseException;

import java.util.List;

record Person(String name, int age) {}

public class Main {
    public static void main(String[] args)
            throws QueryParseException, QueryExecutionException {
        var people = List.of(
                new Person("bob", 10),
                new Person("susan", 25),
                new Person("jo", 3)
        );

        var query = new Query();
        query.parse("""
                SELECT
                    name,
                    age
                FROM
                    example.Person
                WHERE
                    age < 15 AND name.length >= 3
                """);

        System.out.println(query.execute(people).getResults());
    }
}
[[bob, 10]]

See the original documentation on SourceForge for more examples. This can handle some pretty interesting queries.

SELECT *
FROM   java.io.File
WHERE  (name LIKE "%.html"
        OR
        name LIKE "%.txt"
        OR
        name LIKE "%.xml"
       )
AND    lastModified BETWEEN toDate('01-1-2004') AND toDate('31-1-2004')
AND    length >= 10000
ORDER BY lastModified DESC, name, length DESC

Things I did

  • Repackaged to dev.mccue.josql. In the off chance the original library makes a comeback or is a transitive dependency of yours, there won't be conflicts.
  • Replaced all usage of new Double, new Float, new Long, new Short, and new Byte that are deprecated and marked for removal
  • Removed contrib package. This contained convenience classes for ant, jfreechart, jasperreports, jsp, swing, and velocity. Its still in the repo, but I would prefer to publish those separately if at all.
  • Removed JoSQLLogRecordFilter and JoSQLSwingFileFilter so as to not depend on java.desktop or java.logging. Same as for the contrib classes, I can publish them up separately if anyone wants and they are still in the repo for reference.
  • Purposefully did not export
    • dev.mccue.josql.internal - internal is in the name
    • dev.mccue.josql.parser - All the classes here were autogenerated by JavaCC
    • dev.mccue.josql.expressions - seemed to also not have a use for external consumers.
  • Shaded com.gentlyweb.utils into dev.mccue.josql.gentlyweb.utils, hid all its contents, and removed any classes that were not used for JoSQL.
  • Removed support for Apache, ORO, and GNU regexes. If someone wants that back, I would say we can use a service provider. (Again, assuming anyone wants to use this)
  • I confirmed that the manual is tracked on https://web.archive.org/web/20230409212440/http://josql.sourceforge.net/ so if the original site goes down that is available.

Things I did not do

  • Configure the maven build to do the generation of the query parser. The ant build.xml is still in the repo for that purpose, but I have not run it.
  • Really modernize anything. This is still the same pre-generics Java library it was originally.

Why did I do this?

I was up at 4am reading through old libraries and I thought this one was particuarly interesting since I could picture how I could retrofit the (at time of writing) upcoming string templates feature onto it.

And it was possible - with a processor like the following:

package dev.mccue.josql.stringtemplate;

import dev.mccue.josql.Query;
import dev.mccue.josql.QueryParseException;

import java.lang.template.StringTemplate;
import java.lang.template.ValidatingProcessor;
import java.util.Iterator;
import java.util.LinkedHashMap;

public enum QueryProcessor implements ValidatingProcessor<Query, QueryParseException> {
    QUERY;

    @Override
    public Query process(StringTemplate stringTemplate) throws QueryParseException {
        var query = new Query();
        var toSet = new LinkedHashMap<String, Object>();
        StringBuilder sb = new StringBuilder();
        Iterator<String> fragIter = stringTemplate.fragments().iterator();
        int i = 0;
        for (Object value : stringTemplate.values()) {
            sb.append(fragIter.next());
            var sym = ":G_" + i++;
            toSet.put(sym, value);
            sb.append(sym);
        }
        sb.append(fragIter.next());


        query.parse(sb.toString());
        query.setVariables(toSet);

        return query;
    }
}

You can write code like

package dev.mccue.josql.stringtemplate;

import dev.mccue.josql.QueryExecutionException;
import dev.mccue.josql.QueryParseException;

import java.util.List;

import static dev.mccue.josql.stringtemplate.QueryProcessor.QUERY;

record Person(String name, int age) {}

public class Main {
    public static void main(String[] args) 
            throws QueryParseException, QueryExecutionException {
        
        var people = List.of(
                new Person("bob", 10),
                new Person("susan", 25),
                new Person("jo", 3)
        );

        for (int age : List.of(1, 5, 20, 99)) {
            var query = QUERY."""
                SELECT
                    name,
                    age
                FROM
                    dev.mccue.josql.stringtemplate.Person
                WHERE
                    age < \{age}""";

            System.out.println(query.execute(people).getResults());
        }
    }
}
[]
[[jo, 3]]
[[bob, 10], [jo, 3]]
[[bob, 10], [susan, 25], [jo, 3]]

And isn't that neat? I was also pretty shocked to find that it worked out of the box with records considering it predated them by a decade and a half.

Also, I couldn't find a release of it on maven central. That felt a bit sad for a library that seemed genuinely fun to play with.

Support

While I don't plan to overhaul this library or bring it up to date with modern code style, if anyone wants any changes or improvements I am more than willing to take a look or at the very least accept a contribution.

Original Readme Contents

Read the http://josql.sourceforge.net/manual/introduction.html user manual for details on how to use JoSQL.

See:

http://josql.sourceforge.net/manual/version-changes.html

for details of the latest changes, improvements and fixes.

Usage, ensure that JoSQL-X.Y.jar and 3rd-party-jars/gentlyWEB-utils-X.Y.jar are in your classpath.

Also, please note that JoSQL falls under the Apache V2.0 license (a copy of which is found in this distribution), as does the gentlyWEB software (the jar is in 3rd-party-jars). Please contact me: barrygently at users.sourceforge.net (Gary) for a copy of the source. It will soon be released on sourceforge as well (one thing at a time!).