Dynamic SQL for Reporting App - sql

Just about to start playing with jOOQ for a proof of concept. jOOQ looks really simple, expressive and makes SQL maintenance a lot more easier.
We're a Java 8 shop. The usecase here is to write the data layer for a reporting app that dynamically queries tables, columns, filters and functions based on the user selection on the screen.
Although I really like the idea of writing type-safe queries (using the jOOQ codegen), I suppose for my usecase, that won't be a best fit. Because tables, columns etc etc are completely unknown, I suppose I just need the jOOQ SQL builder. That means I have to give up type safety. Is my assessment correct? Or are there any patterns I could use for building "dynamic" SQLs without compromising the type safety? Any pointers would be much appreciated.

You don't have to use jOOQ's code generator to take advantage of most features in jOOQ. The manual's introduction section states that jOOQ can be easily used as a SQL builder without the extra type static safety provided by the code generator:
https://www.jooq.org/doc/latest/manual/getting-started/use-cases/jooq-as-a-standalone-sql-builder
The type safety provided by code generation
The code generator essentially provides two type safety elements:
Names of objects are hard-wired into class names (tables, schemas, sequences, data types, procedures, etc.) and attribute names (columns, type attributes, procedure parameters).
Types of attributes (columns, attributes, parameters) are hard-wired into the generic attribute definitions.
These things certainly helps develop your application
The type safety provided by the jOOQ API
... but beware that the code generator simply reverse engineers a static snapshot of your schema. It is type safe because the entire jOOQ API allows for this kind of type safety. For instance, a Field<T> type has a generic type <T>, which can be used without the code generator as well, e.g. by using the plain SQL APIs:
Field<String> firstName = field(name("USER", "FIRST_NAME"), SQLDataType.VARCHAR(50));
The above API usage (DSL.field(Name, DataType)) does roughly the same as what the code generator would do anyway. It creates a column reference with column type information attached to it. You can use it like the columns generated by the code generator:
DSL.using(configuration)
.select(firstName)
.from(name("USER"))
.where(firstName.like("A%")) // Compiles
.and(firstName.eq(1)) // Doesn't compile: firstName must be compared to String
.join(name("ADDRESS")) // Doesn't compile: the SQL syntax is wrong
.fetch();
As you can see, the only thing that changed compared to using the code generator is the table / column references.
Dynamic SQL
But this means, that jOOQ is even more powerful for you without the code generator. You can still create dynamic SQL statements very easily. For instance:
// Construct your SQL query elements dynamically, and type safely
Condition condition = hasFirstNameFilter()
? firstName.like("A%")
: DSL.trueCondition();
DSL.using(configuration)
.select(firstName)
.from(name("USER"))
.where(condition) // Use dynamically constructed element here
.fetch();
You could also do this in a "functional way":
DSL.using(configuration)
.select(firstName)
.from(name("USER"))
.where(condition()) // Call a function to create the condition here
.fetch();
Or even better
public static Select<Record1<String>> firstNames(
Function<? super Field<String>, ? extends Condition> condition
) {
return
DSL.using(configuration)
.select(firstName)
.from(name("USER"))
.where(condition.apply(firstName)); // Lazy evaluate the predicate here
}
// Use it like this:
firstNames(col -> col.like("A%")).fetch();
Or even better, make the above a higher order function:
public static Function<
? super Function<? super Field<String>, ? extends Condition>,
? extends Select<Record1<String>>
> firstNames() {
// Lazy construct query here
return f -> DSL.using(configuration)
.select(firstName)
.from(name("USER"))
.where(f.apply(firstName)); // Lazy evaluate the predicate here
}
// Use it like this:
firstNames().apply(col -> col.like("A%")).fetch();
More details here:
https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql
Conclusion:
As you can see, while the code generator does add a lot of value for static schemas, there's nothing really static in the jOOQ API. jOOQ is an API for dynamic SQL query construction, that just happens to work well for static queries as well.

Related

How can i configure jOOQ code generator to generate Set<T> instead of Array<T>?

I am working with a database where values are stored in an ARRAY column which has the semantics of a Java Set, most importantly that ordering does not matter.
Currently, the jOOQ generator generates POJOs and Records with Array<T> type for those columns. This is problematic, because two arrays don't equal if their ordering is different.
I tried creating a custom converter, however, obviously defining the toType as Set<String>::class.java won't compile because of type erasure(?)
class ArrayToSetConverter() :
AbstractConverter<Array<String>, Set<String>>(Array<String>::class.java, Set<String>::class.java) { ... }
Compilation error:
Only classes are allowed on the left hand side of a class literal
Is there another way of achieving my goal?
Similar (unfortunately unanswered) question: jOOQ converter from String to List<MyType> in Kotlin
With type erasure, I don't think you can formally create a Class<Set<String>> type reference in neither Java nor kotlin. But you don't have to. Just do this:
class ArrayToSetConverter() : AbstractConverter<Array<String>, Set<String>>(
Array<String>::class.java,
Set::class.java as Class<Set<String>> // Unsafe cast here
) { ... }

Golang SQL rows.Scan function for all fields of generic type

I want to use the Scan() function from the sql package for executing a select statement that might (or not) return multiple rows, and return these results in my function.
I´m new to Golang generics, and am confused about how to achieve this.
Usually, we would use the Scan function on a *sql.Rows and provide the references to all fields of our expected 'result type' we want to read the rows into, e.g.:
var alb Album
rows.Scan(&alb.ID, &alb.Title, &alb.Artist,
&alb.Price, &alb.Quantity)
where Album is a struct type with those five fields shown.
Now, for the purpose of not writing a similar function N times for every SQL table I have, I want to use a generic type R instead. R is of generic interface type Result, and I will define this type as one of N different structs:
type Result interface {
StructA | StructB | StructC
}
func ExecSelect[R Result](conn *sql.DB, cmd Command, template R) []R
How can I now write rows.Scan(...) to apply the Scan operation on all fields of my struct of R´s concrete type? e.g. I would want to have rows.Scan(&res.Field1, &res.Field2, ...) where res is of type R, and Scan should receive all fields of my current concrete type R. And do I actually need to provide a 'template' as argument of R´s concrete type, so that at runtime it becomes clear which struct is now relevant?
Please correct me on any mistake I´m making considering the generics.
This is a poor use case for generics.
The arguments to the function sql.Rows.Scan are supposed to be the scan destinations, i.e. your struct fields, one for each column in the result set, and within the generic function body you do not have access to the fields of R type parameter.
Even if you did, the structs in your Result constraint likely have different fields...? So how do you envision writing generic code that works with different fields?
You might accomplish what you want with a package that provides arbitrary struct scanning like sqlx with facilities like StructScan, but that uses reflection under the hood to map the struct fields into sql.Rows.Scan arguments, so you are not getting any benefit at all with generics.
If anything, you are making it worse, because now you have the additional performance overheads of using type parameters.

EF Core generating bad SQL [duplicate]

I'd like to be able to implement a search method that can take any arbitrary properties of my POCO class as arguments. This works well:
public static IEnumerable<iUser> Search(DataContext context, Func<iUser, bool> predicate)
{
return from i in context.GetTable<iUser>().Where(predicate) select i;
}
but in this case the filtering appears to take place after collecting all the rows in the table.
Is it possible to use Linq to generate an arbitrary query like this without filtering after the sql call? What approaches would you recommend?
Thanks!
LINQ to DB is an Object-Relational Mapper (ORM) that is capable of translating LINQ expressions into SQL. The word "expression" is important here. A Func is not an expression but a delegate, you have to use Expression<Func<>> in LINQ methods for LINQ to DB to be able to translate them. Otherwise the data will be pulled from the database first after which the Func filters them in memory.
So your function should look like:
public static IEnumerable<iUser> Search(DataContext context,
Expression<Func<iUser, bool>> predicate)
{
return context.GetTable<iUser>().Where(predicate);
}
The return type depends on the what you want the caller of this function to be capable of. If you return IQueryable<iUser> the caller will be able to extend the expression by their own expressions. That is, Search(context, somePredicate).Where(...) will be translated into SQL as a whole. Returning IEnumerable will apply any subsequent predicates (either as Func or as Expression) in memory.
Side note, in order to line up with common naming conventions, if iUser is an interface (I have no idea if LINQ to DB supports interfaces) then you should rename it into IUser, otherwise name it User.

Common return type for all ANTLR visitor methods

I'm writing a parser for an old proprietary report specification with ANTLR and I'm currently trying to implement a visitor of the generated parse tree extending the autogenerated abstract visito class.
I have little experience both with ANTLR (which I learned only recently) and with the visitor pattern in general, but if I understood it correctly, the visitor should encapsulate one single operation on the whole data structure (in this case the parse tree), thus sharing the same return type between each Visit*() method.
Taking an example from The Definitive ANTLR 4 Reference book by Terence Parr, to visit a parse tree generated by a grammar that parses a sequence of arithmetic expressions, it feels natural to choose the int return type, as each node of the tree is actually part of the the arithmetic operation that contributes to the final result by the calculator.
Considering my current situation, I don't have a common type: my grammar parses the whole document, which is actually split in different sections with different responsibilities (variable declarations, print options, actual text for the rows, etc...), and I can't find a common type between the result of the visit of so much different nodes, besides object of course.
I tried to think to some possible solutions:
I firstly tried implementing a stateless visitor using object as
the common type, but the amount of type casts needed sounds like a
big red flag to me. I was considering the usage of JSON, but I think
the problem remains, potentially adding some extra overhead in the
serialization process.
I was also thinking about splitting the visitor in more smaller
visitors with a specific purpose (get all the variables, get all the
rows, etc.), but with this solution for each visitor I would
implement only a small subset of the method of the autogenerated
interface (as it is meant to support the visit of the whole tree),
because each visiting operation would probably focus only on a
specific subtree. Is it normal?
Another possibility could be to redesign the data structure so that
it could be used at every level of the tree or, better, define a generic
specification of the nodes that can be used later to build the data
structure. This solution sounds good, but I think it is difficult to
apply in this domain.
A final option could be to switch to a stateful visitor, which
incapsulates one or more builders for the different sections that
each Visit*() method could use to build the data structure
step-by-step. This solution seems to be clean and doable, but I have
difficulties to think about how to scope the result of each visit
operation in the parent scope when needed.
What solution is generally used to visit complex ANTLR parse trees?
ANTLR4 parse trees are often complex because of recursion, e.g.
I would define the class ParsedDocumentModel whose properties would added or modified as your project evolves (which is normal, no program is set in stone).
Assuming your grammar be called Parser in the file Parser.g4, here is sample C# code:
public class ParsedDocumentModel {
public string Title { get; set; }
//other properties ...
}
public class ParserVisitor : ParserBaseVisitor<ParsedDocumentModel>
{
public override ParsedDocumentModel VisitNounz(NounzContext context)
{
var res = "unknown";
var s = context.GetText();
if (s == "products")
res = "<<products>>"; //for example
var model = new ParsedDocumentModel();
model.Title = res; //add more info...
return model;
}
}

Are extensible records useless in Elm 0.19?

Extensible records were one of the most amazing Elm's features, but since v0.16 adding and removing fields is no longer available. And this puts me in an awkward position.
Consider an example. I want to give a name to a random thing t, and extensible records provide me a perfect tool for this:
type alias Named t = { t | name: String }
„Okay,“ says the complier. Now I need a constructor, i.e. a function that equips a thing with specified name:
equip : String -> t -> Named t
equip name thing = { thing | name = name } -- Oops! Type mismatch
Compilation fails, because { thing | name = ... } syntax assumes thing to be a record with name field, but type system can't assure this. In fact, with Named t I've tried to express something opposite: t should be a record type without its own name field, and the function adds this field to a record. Anyway, field addition is necessary to implement equip function.
So, it seems impossible to write equip in polymorphic manner, but it's probably not a such big deal. After all, any time I'm going to give a name to some concrete thing I can do this by hands. Much worse, inverse function extract : Named t -> t (which erases name of a named thing) requires field removal mechanism, and thus is not implementable too:
extract : Named t -> t
extract thing = thing -- Error: No implicit upcast
It would be extremely important function, because I have tons of routines those accept old-fashioned unnamed things, and I need a way to use them for named things. Of course, massive refactoring of those functions is ineligible solution.
At last, after this long introduction, let me state my questions:
Does modern Elm provides some substitute for old deprecated field addition/removal syntax?
If not, is there some built-in function like equip and extract above? For every custom extensible record type I would like to have a polymorphic analyzer (a function that extracts its base part) and a polymorphic constructor (a function that combines base part with additive and produces the record).
Negative answers for both (1) and (2) would force me to implement Named t in a more traditional way:
type Named t = Named String t
In this case, I can't catch the purpose of extensible records. Is there a positive use case, a scenario in which extensible records play critical role?
Type { t | name : String } means a record that has a name field. It does not extend the t type but, rather, extends the compiler’s knowledge about t itself.
So in fact the type of equip is String -> { t | name : String } -> { t | name : String }.
What is more, as you noticed, Elm no longer supports adding fields to records so even if the type system allowed what you want, you still could not do it. { thing | name = name } syntax only supports updating the records of type { t | name : String }.
Similarly, there is no support for deleting fields from record.
If you really need to have types from which you can add or remove fields you can use Dict. The other options are either writing the transformers manually, or creating and using a code generator (this was recommended solution for JSON decoding boilerplate for a while).
And regarding the extensible records, Elm does not really support the “extensible” part much any more – the only remaining part is the { t | name : u } -> u projection so perhaps it should be called just scoped records. Elm docs itself acknowledge the extensibility is not very useful at the moment.
You could just wrap the t type with name but it wouldn't make a big difference compared to approach with custom type:
type alias Named t = { val: t, name: String }
equip : String -> t -> Named t
equip name thing = { val = thing, name = name }
extract : Named t -> t
extract thing = thing.val
Is there a positive use case, a scenario in which extensible records play critical role?
Yes, they are useful when your application Model grows too large and you face the question of how to scale out your application. Extensible records let you slice up the model in arbitrary ways, without committing to particular slices long term. If you sliced it up by splitting it into several smaller nested records, you would be committed to that particular arrangement - which might tend to lead to nested TEA and the 'out message' pattern; usually a bad design choice.
Instead, use extensible records to describe slices of the model, and group functions that operate over particular slices into their own modules. If you later need to work accross different areas of the model, you can create a new extensible record for that.
Its described by Richard Feldman in his Scaling Elm Apps talk:
https://www.youtube.com/watch?v=DoA4Txr4GUs&ab_channel=ElmEurope
I agree that extensible records can seem a bit useless in Elm, but it is a very good thing they are there to solve the scaling issue in the best way.