You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Kotlin is a language with some interesting features which lets you write domain-specific languages (DSL), a language within the language.
It lets you have strongly-typed arguments and lets the IDE provide you with auto-completion for aggregates.
This just scratches the surface of what is possible, it is possible to have strongly typed columns, and use infix functions, operator overloading and other stuff to implement custom operators and keywords to have it more strongly typed with compiler help and less strings.
packageorg.prql_lang.dsl
@DslMarker
annotationclassPrqlDslfunprql(init: PrqlQueryBuilder.() ->Unit): String {
val builder =PrqlQueryBuilder()
builder.init()
return builder.build()
}
/** * Exposes methods to build a PRQL query.*/
@PrqlDsl
classPrqlQueryBuilder {
privatelateinitvar_from:Stringprivatelateinitvar_sort:Stringprivatevar skip:Int=0privatevar take:Int=0privateval columns = mutableListOf<String>()
privateval filters = mutableListOf<String>()
privateval derives = mutableMapOf<String, String>()
/** * Adds a derive. * * @param alias The alias. * @param expression The expression.*/funderive(alias:String, expression:String) {
this.derives.put(alias, expression)
}
funderive(map:Map<String, String>) {
this.derives.putAll(map)
}
/** * Adds a filter predicate. * * @param filter The filter predicate.*/funfilter(filter:String) {
this.filters.add(filter)
}
funfrom(from:String) {
if (::_from.isInitialized) {
throwIllegalStateException("Table already defined")
}
this._from= from
}
funselect(varargcolumns:String) {
if (columns.isEmpty()) {
throwIllegalArgumentException("At least one column should be defined")
}
this.columns.addAll(columns)
}
funselect(columns:List<String>) {
this.columns.addAll(columns)
}
/** * Sorts the elements of a sequence. * * @param sort The key to sort by. * @throws IllegalStateException*/funsort(sort:String) {
if (::_sort.isInitialized) {
throwIllegalStateException("Already sorted")
}
this._sort= sort
}
/** * Returns a specified number of contiguous elements from the start of a sequence. * * @param take The number of elements to return. * @throws IllegalArgumentException*/funtake(take:Int) {
if (take <=0) {
throwIllegalArgumentException("Needs to be greater than zero")
}
this.take = take
}
funtake(range:Iterable<Int>) {
this.skip = range.first()
this.take = range.last()
}
/** * Builds a PRQL query string. * * @return A PRQL query. * @throws IllegalStateException*/funbuild(): String {
if (!::_from.isInitialized) {
throwIllegalStateException("Need call 'from' first")
}
val stringBuilder =StringBuilder()
stringBuilder.appendLine("from $_from")
if (!this.derives.isEmpty())
for ((key, value) in derives)
stringBuilder.appendLine("derive $key = $value")
if (!this.filters.isEmpty())
for (filter in filters)
stringBuilder.appendLine("filter $filter")
if (!this.columns.isEmpty())
stringBuilder.appendLine("select { ${this.columns.joinToString(", ")} }")
if (::_sort.isInitialized)
stringBuilder.appendLine("sort $_sort")
if (this.take !=0)
if (this.skip !=0)
stringBuilder.appendLine("take $skip..$take")
else
stringBuilder.appendLine("take $take")
return stringBuilder.toString()
}
overridefuntoString(): String {
return build()
}
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Kotlin is a language with some interesting features which lets you write domain-specific languages (DSL), a language within the language.
It lets you have strongly-typed arguments and lets the IDE provide you with auto-completion for aggregates.
This just scratches the surface of what is possible, it is possible to have strongly typed columns, and use infix functions, operator overloading and other stuff to implement custom operators and keywords to have it more strongly typed with compiler help and less strings.
You could use it like this.
File:
prql.kt
Beta Was this translation helpful? Give feedback.
All reactions