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)
<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
- 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
, andnew Byte
that are deprecated and marked for removal - Removed
contrib
package. This contained convenience classes forant
,jfreechart
,jasperreports
,jsp
,swing
, andvelocity
. Its still in the repo, but I would prefer to publish those separately if at all. - Removed
JoSQLLogRecordFilter
andJoSQLSwingFileFilter
so as to not depend onjava.desktop
orjava.logging
. Same as for thecontrib
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 namedev.mccue.josql.parser
- All the classes here were autogenerated by JavaCCdev.mccue.josql.expressions
- seemed to also not have a use for external consumers.
- Shaded
com.gentlyweb.utils
intodev.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.
- 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.
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.
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.
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!).