All Projects → RutledgePaulV → q-builders

RutledgePaulV / q-builders

Licence: MIT license
Type safe database agnostic query builders.

Programming Languages

java
68154 projects - #9 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to q-builders

vaultaire
Query DSL and data access utilities for Corda developers.
Stars: ✭ 14 (-71.43%)
Mutual labels:  query-builder, query-dsl
viziquer
Tool for Search in Structured Semantic Data
Stars: ✭ 12 (-75.51%)
Mutual labels:  query-builder
query builder
Compose Ecto queries without effort
Stars: ✭ 56 (+14.29%)
Mutual labels:  query-builder
pinto
Query builder (SQL) in Rust
Stars: ✭ 23 (-53.06%)
Mutual labels:  query-builder
flepper
Flepper is a library to aid in database interaction. 🐸
Stars: ✭ 60 (+22.45%)
Mutual labels:  query-builder
sea-query
🔱 A dynamic SQL query builder for MySQL, Postgres and SQLite
Stars: ✭ 595 (+1114.29%)
Mutual labels:  query-builder
database
Database Abstraction Layer, Schema Introspection, Schema Generation, Query Builders
Stars: ✭ 51 (+4.08%)
Mutual labels:  query-builder
vue-query-builder
A Vue-Query-Builder
Stars: ✭ 71 (+44.9%)
Mutual labels:  query-builder
cqrs
A foundational package for Command Query Responsibility Segregation (CQRS) compatible with Laravel.
Stars: ✭ 37 (-24.49%)
Mutual labels:  query-builder
apollo-studio-community
🎡  GraphQL developer portal featuring an IDE (Apollo Explorer), auto-documentation, metrics reporting, and more. This repo is for issues, feature requests, and preview docs. 📬
Stars: ✭ 212 (+332.65%)
Mutual labels:  query-builder
querie
Compose Ecto query from the client side
Stars: ✭ 20 (-59.18%)
Mutual labels:  query-builder
sparklis
Sparklis is a query builder in natural language that allows people to explore and query SPARQL endpoints with all the power of SPARQL and without any knowledge of SPARQL.
Stars: ✭ 28 (-42.86%)
Mutual labels:  query-builder
database
A php class for managing and connecting to a database
Stars: ✭ 33 (-32.65%)
Mutual labels:  query-builder
goql
Super simple SQL query builder
Stars: ✭ 16 (-67.35%)
Mutual labels:  query-builder
query-filter
🔍 Database/Eloquent Query Builder filters for Laravel
Stars: ✭ 69 (+40.82%)
Mutual labels:  query-builder
buildsqlx
Go database query builder library for PostgreSQL
Stars: ✭ 92 (+87.76%)
Mutual labels:  query-builder
querqy-elasticsearch
Querqy for Elasticsearch
Stars: ✭ 37 (-24.49%)
Mutual labels:  query-builder
indexeddb-orm
Indexed DB ORM
Stars: ✭ 53 (+8.16%)
Mutual labels:  query-builder
aql
asyncio query generator
Stars: ✭ 33 (-32.65%)
Mutual labels:  query-builder
kex
ORM-less for Knex
Stars: ✭ 17 (-65.31%)
Mutual labels:  query-builder

Build Status Coverage Status Maven Central

Overview

A lightweight abstraction for constructing queries oriented around domain models / entities that minimizes magic strings, provides type safety, produces queries that read well, and provides a decoupled way to define new query target formats - allowing you to change your mind about where you store your data without having to change all of your query code.

Why does this exist?

A lot of existing query builders are lacking. It's difficult to write a query builder that is both convenient and safe, which has resulted in most query builders giving up on type safety or allowing you to call methods that don't make sense to be able to call at that time.

Why is this better?

It uses the type system to enforce that you won't call an unapplicable method at any point as you build your queries. Also, there's no need to worry about someone passing an integer to a string field, etc. It supports both chaining and composition to build a query and when used with static imports it becomes a succinct (as far as java goes) query DSL.

Out Of Box Target Formats:

  • Java Predicates
  • A string in RSQL format
  • Elasticsearch's QueryBuilder
  • Spring Data's MongoDB Criteria

Simple Usage:

//--------------------------------------------------------------------------
// define a single query model for each of the models you want to be able to 
// query against. Return the appropriate property interface for each field
// based on the type of the value on your model
//--------------------------------------------------------------------------

public class PersonQuery extends QBuilder<PersonQuery> {

    public StringProperty<PersonQuery> firstName() {
        return stringField("firstName");
    }
    
    public IntegerProperty<PersonQuery> age() {
        return integerField("age");
    }
    
}


Condition<PersonQuery> q = new PersonQuery().firstName().eq("Paul").and().age().eq(23);


String rsql = q.query(new RSQLVisitor()); 
// firstName==Paul;age==23

Criteria mongoCriteria = q.query(new MongoVisitor()); 
// {firstName: "Paul", age: 23}

FilterBuilder filter = q.query(new ElasticsearchVisitor());
// { "and" : { "filters" : [ { "term" : { "firstName" : "Paul" } }, { "term" : { "age" : 23 } } ] } }

Predicate<Person> predicate = q.query(new PredicateVisitor<>());
// List<Person> personsNamedPaulAndAge23 = persons.stream().filter(predicate).collect(toList());

Static Import Usage:

public class PersonQuery extends QBuilder<PersonQuery> {

    public static StringProperty<PersonQuery> firstName() {
        return new PersonQuery().stringField("firstName");
    }
    
    public static IntegerProperty<PersonQuery> age() {
        return new PersonQuery().integerField("age");
    }
    
}

import static com.company.queries.PersonQuery.*;

Condition<PersonQuery> query = firstName().eq("Paul").or(and(firstName().ne("Richard"), age().gt(22)));

Precedence:

Chaining with the infix forms of and() and or() is complicated when you use both and then want to talk about precedence. The implementation is such that whenever you change from a chain of and() to a chain of or() (or vice versa), then the previous statements are wrapped together and the existing set becomes one of the elements in the new or() (or and()) chain.

In general, to avoid unintended precedence concerns, it's best to limit your chains to only and() or or() operators and use the compositional forms and(Condition<T> c1, Condition<T> c2, Condition<T>... cn) and or(Condition<T> c1, Condition<T> c2, Condition<T>... cn) for queries that must mix the two.

Common Use Cases

Such-&-Such Isn't Easy to Use or Type Safe

Many criteria / query builders don't provide much in the way of a good "user experience". You can use q-builders simply because they provide an improvement over these.

I Might Change Datastores

By using a layer that provides some decoupling from your storage, if you decide to swap out a datastore for something else but you're not also changing your data's structure then you can just write a new target backend and keep your query building the same.

I'm Providing a Rest API

Chances are you want to provide an ability for people to query against your API, but you also make queries against the database yourself in the implementation of business logic on the server. One option could be to use these builders to define one query model in a shared jar that you use in both your SDK and API and simply target different query formats. Like RSQL for over-the-wire and directly into mongo criteria on the API server.

RSQL Flavor

The RSQL builder introduces some new operators to the standard RSQL set. Since this library only builds queries it doesn't dictate what you use to parse them. However, it's written specifically to be compatible with rsql-parser. So, you should make sure that you add the following operators before parsing:

  • "=ex=" The exists clause. It has values of either true or false.
  • "=q=" The subquery clause. It has a string value that itself might be an entire RSQL query.
  • "=re=" A regular expression as a string. The string will be passed as-is to the backend visitor you use, so the regex string must be in the same flavor as the visitor you intend to use (mongo regex vs java regex, etc)

Installation

Release Versions

<dependencies>
    <dependency>
        <groupId>com.github.rutledgepaulv</groupId>
        <artifactId>q-builders</artifactId>
        <version>1.5</version>
    </dependency>
</dependencies>

Snapshot Versions

<dependencies>
    <dependency>
        <groupId>com.github.rutledgepaulv</groupId>
        <artifactId>q-builders</artifactId>
        <version>1.6-SNAPSHOT</version>
    </dependency>
</dependencies>


<repositories>
    <repository>
        <id>ossrh</id>
        <name>Repository for snapshots</name>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>

Optional dependencies

<dependencies>
    
    <!-- only necessary if you're using the spring data mongodb criteria target type -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>1.9.2.RELEASE</version>
    </dependency>
    
    <!-- only necessary if you're using the elasticsearch filter builder target type -->
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>2.3.4</version>
    </dependency>
            
</dependencies>

License

This project is licensed under MIT license.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].