Repository: x2bool/kuery
Branch: master
Commit: 18671cd841c3
Files: 38
Total size: 94.0 KB
Directory structure:
gitextract_cz49ip86/
├── .gitignore
├── LICENSE
├── README.md
├── bintray.gradle
├── build.gradle
├── core/
│ ├── build.gradle
│ └── src/
│ └── tel/
│ └── egram/
│ └── kuery/
│ ├── Dialect.kt
│ ├── Predicate.kt
│ ├── Subject.kt
│ ├── Table.kt
│ ├── ddl/
│ │ ├── CreateTableStatement.kt
│ │ ├── Definition.kt
│ │ └── DropTableStatement.kt
│ └── dml/
│ ├── Assignment.kt
│ ├── DeleteStatement.kt
│ ├── GroupClause.kt
│ ├── HavingClause.kt
│ ├── InsertStatement.kt
│ ├── JoinClause.kt
│ ├── LimitClause.kt
│ ├── OffsetClause.kt
│ ├── OrderClause.kt
│ ├── Ordering.kt
│ ├── Projection.kt
│ ├── SelectStatement.kt
│ ├── UpdateStatement.kt
│ └── WhereClause.kt
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── sample-maven.properties
├── settings.gradle
└── sqlite/
├── build.gradle
├── src/
│ └── tel/
│ └── egram/
│ └── kuery/
│ └── sqlite/
│ ├── SQLiteDefinition.kt
│ └── SQLiteDialect.kt
└── test/
└── tel/
└── egram/
└── kuery/
└── sqlite/
└── tests/
└── SQLiteDialectTest.kt
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
build/
.gradle/
.idea/
*.iml
maven.properties
local.properties
.DS_Store
out
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2016 Sergey Khabibullin
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
# Kuery - strongly typed SQL in Kotlin
The library is a strongly typed alternative to plain text SQL. The main goal of this project is to make database-related code easier to develop and maintain. The project uses some of the Kotlin language features to achieve type safety.
## Features
* SQL-like syntax. Use language constructions you already know. Designed to cover the most common SQL features.
* Strongly typed DSL makes it harder to make mistakes. Some of the most common errors are catched at compile time.
* IDE's assist in code editing.
* Easier and safer refactoring/renaming.
* No reflection
## Foundation
Database structure is defined by classes/objects inherited from the **Table** class. Tables are **not** domain model classes. Their purpose is to simply define relationships between tables and columns.
```kotlin
import tel.egram.kuery.*
object Organizations : Table("organizations") {
val id = Column("id")
val name = Column("name")
}
object Employees : Table("employees") {
val id = Column("id")
val name = Column("name")
val organizationId = Column("organization_id")
}
```
**Statements** are the building blocks of the library. A statement usually starts with one of the following function calls:
* over(table) - used for **CREATE TABLE** and **DROP TABLE** statements
* into(table) - used for **INSERT** statements
* from(table) - used for **SELECT**, **UPDATE** and **DELETE** statements
**Dialects** are responsible for converting statements into actual SQL:
```kotlin
import tel.egram.kuery.*
import tel.egram.kuery.sqlite.*
val statement = from(Employees).where { e -> e.id eq 1 }.select { e -> e.name }
val sql = statement.toString(SQLiteDialect)
print(sql) // SELECT "name" FROM "employees" WHERE "id" = 1
```
## Data Definition Language
Some parts of data definition language are specific to SQL dialects. An example for SQLite might look like this:
### CREATE TABLE statement
```kotlin
import tel.egram.kuery.*
import tel.egram.kuery.sqlite.*
// CREATE TABLE "organizations" ...
over(Organizations)
.create {
integer(it.id).primaryKey(autoIncrement = true)..
text(it.name).unique().notNull()
}
// CREATE TABLE "employees" ...
over(Employees)
.create {
integer(it.id).primaryKey(autoIncrement = true)..
text(it.name).unique().notNull()..
integer(it.organizationId).foreignKey(references = Organizations.id)
}
```
### DROP TABLE statement
```kotlin
// DROP TABLE "employees"
over(Employees).drop()
```
## Data Manipulation Language
Data manipulation is the most powerfull and complex part of SQL. The library supports **INSERT**, **SELECT**, **UPDATE** and **DELETE** statements.
### INSERT statement
```kotlin
// INSERT INTO "employees"("name", "organization_id") VALUES("John Doe", 1)
into(Employees)
.insert { e -> e.name("John Doe") .. e.organizationId(1) }
```
### SELECT statement
The library provides the following operators to compose queries:
* and
* or
* not
* eq (equals)
* ne (not equals)
* lt (less than)
* lte (less than or equal to)
* gt (greater than)
* gte (greater than or equal to)
```kotlin
// SELECT "id", "name" FROM "organizations" WHERE ...
from(Employees)
.where { e -> (e.organizationId ne null) and (e.name eq "John Doe") }
.groupBy { e -> e.name }
.having { e -> e.id ne null }
.orderBy { e -> e.name.asc .. e.id.desc }
.limit { 10 }
.offset { 10 }
.select { e -> e.id .. e.name }
```
**JOINs** are also supported in select statements
```kotlin
// SELECT ... FROM "organizations" JOIN "employees" ON ...
from(Organizations)
.join(Employees).on { o, e -> o.id eq e.organizationId }
.select { o, e -> o.name .. e.name }
```
### UPDATE statement
```kotlin
// UPDATE "organizations" SET "name" = 'John Doe' WHERE "id" = 1
from(Organizations)
.where { o -> o.id eq 1 }
.update { o -> o.name("John Doe") }
```
### DELETE statement
```kotlin
// DELETE FROM "organizations" WHERE "id" = 0
from(Organizations)
.where { o -> o.id eq 0 }
.delete()
```
## Download
Maven:
```xml
tel.egram.kuery
core
0.5.3
pom
tel.egram.kuery
sqlite
0.5.3
pom
```
Gradle:
```groovy
// Core library
compile 'tel.egram.kuery:core:0.5.3'
// SQLite dialect
compile 'tel.egram.kuery:sqlite:0.5.3'
```
================================================
FILE: bintray.gradle
================================================
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.bintray'
defaultTasks 'jar'
task sourcesJar(type: Jar, dependsOn: project.classes) {
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: project.javadoc) {
from javadoc.destinationDir
}
artifacts {
archives sourcesJar, javadocJar
}
def projDescription = 'Strongly typed alternative to plain text SQL. Powered by Kotlin.'
project.ext.set("bintray_repo", "")
if (file("${rootProject.projectDir}/maven.properties").exists()) {
Properties properties = new Properties()
properties.load(new FileInputStream("${rootProject.projectDir}/maven.properties"))
properties.each { prop ->
project.ext.set(prop.key, prop.value)
}
}
publishing {
publications {
"${project.name}"(MavenPublication) {
pom.withXml {
asNode().appendNode('description', projDescription)
}
groupId rootProject.group_id
artifactId project.name
version rootProject.ext.version_name
artifact sourcesJar { classifier = 'sources' }
artifact javadocJar { classifier = 'javadoc' }
from components.java
}
}
repositories {
maven {
url "$bintray_repo"
}
maven {
url "https://jitpack.io"
}
}
}
bintray {
user = project.ext.properties.containsKey("bintray_user") ? project.ext.get("bintray_user") : System.getenv('BINTRAY_USER')
key = project.ext.properties.containsKey("bintray_apikey") ? project.ext.get("bintray_apikey") : System.getenv('BINTRAY_API_KEY')
publications = [project.name]
pkg {
repo = 'maven'
name = 'kuery'
userOrg = 'egram'
licenses = ['MIT']
vcsUrl = 'https://github.com/x2bool/kuery.git'
publish = true
publicDownloadNumbers = true
version {
name = rootProject.ext.version_name
desc = projDescription
released = new Date()
vcsTag = rootProject.ext.version_name
}
}
}
bintrayUpload.dependsOn "generatePomFileFor${project.name.capitalize()}Publication"
================================================
FILE: build.gradle
================================================
buildscript {
ext.kotlin_version = '1.2.41'
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1+"
}
}
ext.group_id = 'tel.egram.kuery'
ext.version_name = '0.5.3'
allprojects {
apply plugin: 'maven'
repositories {
jcenter()
mavenCentral()
}
}
================================================
FILE: core/build.gradle
================================================
apply plugin: 'kotlin'
apply from: "${rootProject.rootDir}/bintray.gradle"
sourceSets {
main.kotlin.srcDirs += 'src'
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
================================================
FILE: core/src/tel/egram/kuery/Dialect.kt
================================================
package tel.egram.kuery
import tel.egram.kuery.ddl.*
import tel.egram.kuery.dml.*
interface Dialect {
fun build(statement: CreateTableStatement): String
fun build(statement: DropTableStatement): String
fun build(statement: SelectStatement): String
fun build(statement: Select2Statement): String
fun build(statement: Select3Statement): String
fun build(statement: Select4Statement): String
fun build(statement: InsertStatement): String
fun build(statement: UpdateStatement): String
fun build(statement: DeleteStatement): String
}
================================================
FILE: core/src/tel/egram/kuery/Predicate.kt
================================================
package tel.egram.kuery
interface Predicate
/**
* Not expression
*/
class NotExpression(val param: Any?) : Predicate
fun not(predicate: Predicate): NotExpression {
return NotExpression(predicate)
}
/**
* And expression
*/
class AndExpression(val left: Any?, val right: Any?) : Predicate
infix fun Predicate.and(predicate: Predicate): AndExpression {
return AndExpression(this, predicate)
}
/**
* Or expression
*/
class OrExpression(val left: Any?, val right: Any?) : Predicate
infix fun Predicate.or(predicate: Predicate): OrExpression {
return OrExpression(this, predicate)
}
/**
* Equals expression
*/
class EqExpression(val left: Any?, val right: Any?) : Predicate
infix fun Table.Column.eq(column: Table.Column): EqExpression {
return EqExpression(this, column)
}
infix fun Table.Column.eq(str: String?): EqExpression {
return EqExpression(this, str)
}
infix fun Table.Column.eq(num: Number): EqExpression {
return EqExpression(this, num)
}
infix fun Table.Column.eq(flag: Boolean): EqExpression {
return EqExpression(this, flag)
}
/**
* Not equals expression
*/
class NeExpression(val left: Any?, val right: Any?) : Predicate
infix fun Table.Column.ne(column: Table.Column): NeExpression {
return NeExpression(this, column)
}
infix fun Table.Column.ne(str: String?): NeExpression {
return NeExpression(this, str)
}
infix fun Table.Column.ne(num: Number): NeExpression {
return NeExpression(this, num)
}
infix fun Table.Column.ne(flag: Boolean): NeExpression {
return NeExpression(this, flag)
}
/**
* Less than expression
*/
class LtExpression(val left: Any?, val right: Any?) : Predicate
infix fun Table.Column.lt(column: Table.Column): LtExpression {
return LtExpression(this, column)
}
infix fun Table.Column.lt(str: String?): LtExpression {
return LtExpression(this, str)
}
infix fun Table.Column.lt(num: Number): LtExpression {
return LtExpression(this, num)
}
/**
* Less than or equal expression
*/
class LteExpression(val left: Any?, val right: Any?) : Predicate
infix fun Table.Column.lte(column: Table.Column): LteExpression {
return LteExpression(this, column)
}
infix fun Table.Column.lte(str: String?): LteExpression {
return LteExpression(this, str)
}
infix fun Table.Column.lte(num: Number): LteExpression {
return LteExpression(this, num)
}
/**
* Greater than expression
*/
class GtExpression(val left: Any?, val right: Any?) : Predicate
infix fun Table.Column.gt(column: Table.Column): GtExpression {
return GtExpression(this, column)
}
infix fun Table.Column.gt(str: String?): GtExpression {
return GtExpression(this, str)
}
infix fun Table.Column.gt(num: Number): GtExpression {
return GtExpression(this, num)
}
/**
* Greater than or equal expression
*/
class GteExpression(val left: Any?, val right: Any?) : Predicate
infix fun Table.Column.gte(column: Table.Column): GteExpression {
return GteExpression(this, column)
}
infix fun Table.Column.gte(str: String?): GteExpression {
return GteExpression(this, str)
}
infix fun Table.Column.gte(num: Number): GteExpression {
return GteExpression(this, num)
}
================================================
FILE: core/src/tel/egram/kuery/Subject.kt
================================================
package tel.egram.kuery
import tel.egram.kuery.ddl.*
import tel.egram.kuery.dml.*
open class Subject {
val table: T
private constructor(table: T) {
this.table = table
}
override fun toString(): String {
return table.toString()
}
class Over(table: T) : Subject(table) {
inline fun create(definition: (T) -> Iterable): CreateTableStatement {
return CreateTableStatement(definition(table), this)
}
inline fun drop(): DropTableStatement {
return DropTableStatement(this)
}
}
class From(table: T) : Subject(table) {
inline fun join(table2: T2): Join2Clause {
return Join2Clause(this, table2)
}
inline fun outerJoin(table2: T2): Join2Clause {
return Join2Clause(this, table2, JoinType.OUTER)
}
inline fun where(predicate: (T) -> Predicate): WhereClause {
return WhereClause(predicate(table), this)
}
inline fun groupBy(projection: (T) -> Iterable): GroupClause {
return GroupClause(projection(table), this, null)
}
inline fun orderBy(order: (T) -> Iterable): OrderClause {
return OrderClause(order(table), this, null, null, null)
}
inline fun limit(limit: () -> String): LimitClause {
return LimitClause(
limit(),
this,
null,
null,
null,
null)
}
inline fun offset(offset: () -> String): OffsetClause {
return OffsetClause(
offset(),
limit { "-1" },
this,
null,
null,
null,
null)
}
inline fun select(projection: (T) -> Iterable): SelectStatement {
return SelectStatement(
projection(table),
this,
null,
null,
null,
null,
null,
null)
}
inline fun update(update: (T) -> Iterable): UpdateStatement {
return UpdateStatement(
update(table),
this,
null)
}
inline fun delete(): DeleteStatement {
return DeleteStatement(
this,
null
)
}
}
class Into(table: T) : Subject(table) {
inline fun insert(insert: (T) -> Iterable): InsertStatement {
return InsertStatement(insert(table), this)
}
}
}
inline fun over(table: T): Subject.Over {
return Subject.Over(table)
}
inline fun from(table: T): Subject.From {
return Subject.From(table)
}
inline fun into(table: T): Subject.Into {
return Subject.Into(table)
}
================================================
FILE: core/src/tel/egram/kuery/Table.kt
================================================
package tel.egram.kuery
import tel.egram.kuery.ddl.Definition
import tel.egram.kuery.dml.*
open class Table(private val name: String) {
inner class Column(val name: String) : Projection {
val table: Table
get() = this@Table
val asc: Ordering
get() = Ordering.By(this, true)
val desc: Ordering
get() = Ordering.By(this, false)
operator fun invoke(column: Column): Assignment {
return Assignment.Value(this, column)
}
operator fun invoke(value: String?): Assignment {
return Assignment.Value(this, value)
}
operator fun invoke(value: Number): Assignment {
return Assignment.Value(this, value)
}
operator fun invoke(value: Boolean): Assignment {
return Assignment.Value(this, value)
}
override fun toString(): String {
return name
}
}
override fun toString(): String {
return name
}
}
operator fun Table.Column.rangeTo(column: Table.Column): Iterable {
return listOf(this, column)
}
operator fun Iterable.rangeTo(column: Table.Column): Iterable {
return this.plusElement(column)
}
operator fun Iterable.rangeTo(ordering: Ordering): Iterable {
return if (this is Ordering) listOf(this, ordering) else this.plusElement(ordering)
}
operator fun Iterable.rangeTo(assignment: Assignment): Iterable {
return if (this is Assignment) listOf(this, assignment) else this.plusElement(assignment)
}
operator fun Iterable.rangeTo(definition: Definition): Iterable {
return if (this is Definition) listOf(this, definition) else this.plusElement(definition)
}
================================================
FILE: core/src/tel/egram/kuery/ddl/CreateTableStatement.kt
================================================
package tel.egram.kuery.ddl
import tel.egram.kuery.*
class CreateTableStatement(
val definitions: Iterable,
val subject: Subject) {
fun toString(dialect: Dialect): String {
return dialect.build(this)
}
}
================================================
FILE: core/src/tel/egram/kuery/ddl/Definition.kt
================================================
package tel.egram.kuery.ddl
import tel.egram.kuery.*
interface Definition : Iterable {
val column: Table.Column
val type: String
override fun iterator(): Iterator {
return object : Iterator {
var valid = true
override fun hasNext(): Boolean {
return valid
}
override fun next(): Definition {
valid = false
return this@Definition
}
}
}
open class Column(override val column: Table.Column, override val type: String) : Definition
}
================================================
FILE: core/src/tel/egram/kuery/ddl/DropTableStatement.kt
================================================
package tel.egram.kuery.ddl
import tel.egram.kuery.*
class DropTableStatement(
val subject: Subject) {
fun toString(dialect: Dialect): String {
return dialect.build(this)
}
}
================================================
FILE: core/src/tel/egram/kuery/dml/Assignment.kt
================================================
package tel.egram.kuery.dml
import tel.egram.kuery.Table
interface Assignment : Iterable {
val column: Table.Column
val value: Any?
override fun iterator(): Iterator {
return object : Iterator {
var valid = true
override fun hasNext(): Boolean {
return valid
}
override fun next(): Assignment {
valid = false
return this@Assignment
}
}
}
class Value(override val column: Table.Column, override val value: Any?) : Assignment
}
================================================
FILE: core/src/tel/egram/kuery/dml/DeleteStatement.kt
================================================
package tel.egram.kuery.dml
import tel.egram.kuery.*
class DeleteStatement(
val subject: Subject,
val whereClause: WhereClause?) {
fun toString(dialect: Dialect): String {
return dialect.build(this)
}
}
================================================
FILE: core/src/tel/egram/kuery/dml/GroupClause.kt
================================================
package tel.egram.kuery.dml
import tel.egram.kuery.*
class GroupClause(
val projection: Iterable,
val subject: Subject,
val whereClause: WhereClause?) {
inline fun having(predicate: (T) -> Predicate): HavingClause {
return HavingClause(predicate(subject.table), subject, this, whereClause)
}
inline fun orderBy(order: (T) -> Iterable): OrderClause {
return OrderClause(order(subject.table), subject, whereClause, this, null)
}
inline fun limit(limit: () -> Any): LimitClause {
return LimitClause(
limit(),
subject,
whereClause,
null,
this,
null)
}
inline fun offset(offset: () -> Any): OffsetClause {
return OffsetClause(
offset(),
limit { "-1" },
subject,
whereClause,
null,
this,
null)
}
inline fun select(projection: (T) -> Iterable): SelectStatement {
return SelectStatement(
projection(subject.table),
subject,
whereClause,
null,
null,
null,
this,
null
)
}
}
class Group2Clause(
val projection: Iterable,
val joinOn2Clause: JoinOn2Clause,
val where2Clause: Where2Clause?) {
inline fun having(predicate: (T, T2) -> Predicate): Having2Clause {
return Having2Clause(
predicate(joinOn2Clause.subject.table, joinOn2Clause.table2),
joinOn2Clause,
this,
where2Clause)
}
inline fun orderBy(order: (T, T2) -> Iterable): Order2Clause {
return Order2Clause(order(joinOn2Clause.subject.table, joinOn2Clause.table2), joinOn2Clause, where2Clause, this, null)
}
inline fun limit(limit: () -> Any): Limit2Clause {
return Limit2Clause(
limit(),
joinOn2Clause,
where2Clause,
null,
this,
null)
}
inline fun offset(offset: () -> Any): Offset2Clause {
return Offset2Clause(
offset(),
limit { "-1" },
joinOn2Clause,
where2Clause,
null,
this,
null)
}
inline fun select(projection: (T, T2) -> Iterable): Select2Statement {
return Select2Statement(
projection(joinOn2Clause.subject.table, joinOn2Clause.table2),
joinOn2Clause,
where2Clause,
null,
null,
null,
this,
null
)
}
}
class Group3Clause(
val projection: Iterable,
val joinOn3Clause: JoinOn3Clause,
val where3Clause: Where3Clause?) {
inline fun having(predicate: (T, T2, T3) -> Predicate): Having3Clause {
return Having3Clause(
predicate(
joinOn3Clause.joinOn2Clause.subject.table,
joinOn3Clause.joinOn2Clause.table2,
joinOn3Clause.table3),
joinOn3Clause,
this,
where3Clause)
}
inline fun orderBy(order: (T, T2, T3) -> Iterable): Order3Clause {
return Order3Clause(
order(joinOn3Clause.joinOn2Clause.subject.table, joinOn3Clause.joinOn2Clause.table2, joinOn3Clause.table3), joinOn3Clause, where3Clause, this, null)
}
inline fun limit(limit: () -> Any): Limit3Clause {
return Limit3Clause(
limit(),
joinOn3Clause,
where3Clause,
null,
this,
null)
}
inline fun offset(offset: () -> Any): Offset3Clause {
return Offset3Clause(
offset(),
limit { "-1" },
joinOn3Clause,
where3Clause,
null,
this,
null)
}
inline fun select(projection: (T, T2, T3) -> Iterable): Select3Statement {
return Select3Statement(
projection(
joinOn3Clause.joinOn2Clause.subject.table,
joinOn3Clause.joinOn2Clause.table2,
joinOn3Clause.table3
),
joinOn3Clause,
where3Clause,
null,
null,
null,
this,
null
)
}
}
class Group4Clause(
val projection: Iterable,
val joinOn4Clause: JoinOn4Clause,
val where4Clause: Where4Clause?) {
inline fun having(predicate: (T, T2, T3, T4) -> Predicate): Having4Clause {
return Having4Clause(
predicate(
joinOn4Clause.joinOn3Clause.joinOn2Clause.subject.table,
joinOn4Clause.joinOn3Clause.joinOn2Clause.table2,
joinOn4Clause.joinOn3Clause.table3,
joinOn4Clause.table4),
joinOn4Clause,
this,
where4Clause)
}
inline fun orderBy(order: (T, T2, T3, T4) -> Iterable): Order4Clause {
return Order4Clause(
order(
joinOn4Clause.joinOn3Clause.joinOn2Clause.subject.table,
joinOn4Clause.joinOn3Clause.joinOn2Clause.table2,
joinOn4Clause.joinOn3Clause.table3,
joinOn4Clause.table4
),
joinOn4Clause,
where4Clause,
this,
null)
}
inline fun limit(limit: () -> Any): Limit4Clause {
return Limit4Clause(
limit(),
joinOn4Clause,
where4Clause,
null,
this,
null)
}
inline fun offset(offset: () -> Any): Offset4Clause {
return Offset4Clause(
offset(),
limit { "-1" },
joinOn4Clause,
where4Clause,
null,
this,
null)
}
inline fun select(projection: (T, T2, T3, T4) -> Iterable): Select4Statement {
return Select4Statement(
projection(
joinOn4Clause.joinOn3Clause.joinOn2Clause.subject.table,
joinOn4Clause.joinOn3Clause.joinOn2Clause.table2,
joinOn4Clause.joinOn3Clause.table3,
joinOn4Clause.table4
),
joinOn4Clause,
where4Clause,
null,
null,
null,
this,
null
)
}
}
================================================
FILE: core/src/tel/egram/kuery/dml/HavingClause.kt
================================================
package tel.egram.kuery.dml
import tel.egram.kuery.*
class HavingClause(
val predicate: Predicate,
val subject: Subject,
val groupClause: GroupClause,
val whereClause: WhereClause?) {
inline fun orderBy(order: (T) -> Iterable): OrderClause {
return OrderClause(order(subject.table), subject, whereClause, groupClause, this)
}
inline fun limit(limit: () -> Any): LimitClause {
return LimitClause(
limit(),
subject,
whereClause,
null,
groupClause,
this)
}
inline fun offset(offset: () -> Any): OffsetClause {
return OffsetClause(
offset(),
limit { "-1" },
subject,
whereClause,
null,
groupClause,
this)
}
inline fun select(projection: (T) -> Iterable): SelectStatement {
return SelectStatement(
projection(subject.table),
subject,
whereClause,
null,
null,
null,
groupClause,
this)
}
}
class Having2Clause(
val predicate: Predicate,
val joinOn2Clause: JoinOn2Clause,
val group2Clause: Group2Clause,
val where2Clause: Where2Clause?) {
inline fun orderBy(order: (T, T2) -> Iterable): Order2Clause {
return Order2Clause(order(joinOn2Clause.subject.table, joinOn2Clause.table2), joinOn2Clause, where2Clause, group2Clause, this)
}
inline fun limit(limit: () -> Any): Limit2Clause {
return Limit2Clause(
limit(),
joinOn2Clause,
where2Clause,
null,
group2Clause,
this)
}
inline fun offset(offset: () -> Any): Offset2Clause {
return Offset2Clause(
offset(),
limit { "-1" },
joinOn2Clause,
where2Clause,
null,
group2Clause,
this)
}
inline fun select(projection: (T, T2) -> Iterable): Select2Statement {
return Select2Statement(
projection(joinOn2Clause.subject.table, joinOn2Clause.table2),
joinOn2Clause,
where2Clause,
null,
null,
null,
group2Clause,
this
)
}
}
class Having3Clause(
val predicate: Predicate,
val joinOn3Clause: JoinOn3Clause,
val group3Clause: Group3Clause,
val where3Clause: Where3Clause?) {
inline fun orderBy(order: (T, T2, T3) -> Iterable): Order3Clause {
return Order3Clause(
order(joinOn3Clause.joinOn2Clause.subject.table, joinOn3Clause.joinOn2Clause.table2, joinOn3Clause.table3), joinOn3Clause, where3Clause, group3Clause, this)
}
inline fun limit(limit: () -> Any): Limit3Clause {
return Limit3Clause(
limit(),
joinOn3Clause,
where3Clause,
null,
group3Clause,
this)
}
inline fun offset(offset: () -> Any): Offset3Clause {
return Offset3Clause(
offset(),
limit { "-1" },
joinOn3Clause,
where3Clause,
null,
group3Clause,
this)
}
inline fun select(projection: (T, T2, T3) -> Iterable): Select3Statement {
return Select3Statement(
projection(
joinOn3Clause.joinOn2Clause.subject.table,
joinOn3Clause.joinOn2Clause.table2,
joinOn3Clause.table3
),
joinOn3Clause,
where3Clause,
null,
null,
null,
group3Clause,
this
)
}
}
class Having4Clause(
val predicate: Predicate,
val joinOn4Clause: JoinOn4Clause,
val group4Clause: Group4Clause,
val where4Clause: Where4Clause?) {
inline fun orderBy(order: (T, T2, T3, T4) -> Iterable): Order4Clause {
return Order4Clause(
order(
joinOn4Clause.joinOn3Clause.joinOn2Clause.subject.table,
joinOn4Clause.joinOn3Clause.joinOn2Clause.table2,
joinOn4Clause.joinOn3Clause.table3,
joinOn4Clause.table4
),
joinOn4Clause,
where4Clause,
group4Clause,
this)
}
inline fun limit(limit: () -> Any): Limit4Clause {
return Limit4Clause(
limit(),
joinOn4Clause,
where4Clause,
null,
group4Clause,
this)
}
inline fun offset(offset: () -> Any): Offset4Clause {
return Offset4Clause(
offset(),
limit { "-1" },
joinOn4Clause,
where4Clause,
null,
group4Clause,
this)
}
inline fun select(projection: (T, T2, T3, T4) -> Iterable): Select4Statement {
return Select4Statement(
projection(
joinOn4Clause.joinOn3Clause.joinOn2Clause.subject.table,
joinOn4Clause.joinOn3Clause.joinOn2Clause.table2,
joinOn4Clause.joinOn3Clause.table3,
joinOn4Clause.table4
),
joinOn4Clause,
where4Clause,
null,
null,
null,
group4Clause,
this
)
}
}
================================================
FILE: core/src/tel/egram/kuery/dml/InsertStatement.kt
================================================
package tel.egram.kuery.dml
import tel.egram.kuery.*
class InsertStatement(
val assignments: Iterable,
val subject: Subject) {
fun toString(dialect: Dialect): String {
return dialect.build(this)
}
}
================================================
FILE: core/src/tel/egram/kuery/dml/JoinClause.kt
================================================
package tel.egram.kuery.dml
import tel.egram.kuery.*
class Join2Clause(
val subject: Subject,
val table2: T2,
val type: JoinType = JoinType.INNER) {
inline fun on(condition: (T, T2) -> Predicate): JoinOn2Clause {
return JoinOn2Clause(
subject,
table2,
type,
condition(subject.table, table2)
)
}
}
class JoinOn2Clause(
val subject: Subject,
val table2: T2,
val type: JoinType,
val condition: Predicate) {
inline fun join(table3: T3): Join3Clause {
return Join3Clause(this, table3)
}
inline fun outerJoin(table3: T3): Join3Clause {
return Join3Clause(this, table3, JoinType.OUTER)
}
inline fun where(predicate: (T, T2) -> Predicate): Where2Clause {
return Where2Clause(predicate(subject.table, table2), this)
}
inline fun groupBy(group: (T, T2) -> Iterable): Group2Clause {
return Group2Clause(group(subject.table, table2), this, null)
}
inline fun orderBy(order: (T, T2) -> Iterable): Order2Clause {
return Order2Clause(order(subject.table, table2), this, null, null, null)
}
inline fun limit(limit: () -> Any): Limit2Clause {
return Limit2Clause(
limit(),
this,
null,
null,
null,
null)
}
inline fun offset(offset: () -> String): Offset2Clause {
return Offset2Clause(
offset(),
limit { "-1" },
this,
null,
null,
null,
null)
}
inline fun select(projection: (T, T2) -> Iterable): Select2Statement {
return Select2Statement(
projection(subject.table, table2),
this,
null,
null,
null,
null,
null,
null)
}
}
class Join3Clause(
val joinOn2Clause: JoinOn2Clause,
val table3: T3,
val type: JoinType = JoinType.INNER) {
inline fun on(condition: (T, T2, T3) -> Predicate): JoinOn3Clause {
return JoinOn3Clause(
joinOn2Clause,
table3,
type,
condition(joinOn2Clause.subject.table, joinOn2Clause.table2, table3)
)
}
}
class JoinOn3Clause(
val joinOn2Clause: JoinOn2Clause,
val table3: T3,
val type: JoinType,
val condition: Predicate) {
inline fun join(table4: T4): Join4Clause {
return Join4Clause(this, table4)
}
inline fun outerJoin(table4: T4): Join4Clause {
return Join4Clause(this, table4, JoinType.OUTER)
}
inline fun where(predicate: (T, T2, T3) -> Predicate): Where3Clause {
return Where3Clause(predicate(joinOn2Clause.subject.table, joinOn2Clause.table2, table3), this)
}
inline fun groupBy(group: (T, T2, T3) -> Iterable): Group3Clause {
return Group3Clause(
group(joinOn2Clause.subject.table, joinOn2Clause.table2, table3),
this,
null
)
}
inline fun orderBy(order: (T, T2, T3) -> Iterable): Order3Clause {
return Order3Clause(
order(joinOn2Clause.subject.table, joinOn2Clause.table2, table3),
this,
null,
null,
null
)
}
inline fun limit(limit: () -> Any): Limit3Clause {
return Limit3Clause(
limit(),
this,
null,
null,
null,
null)
}
inline fun offset(offset: () -> String): Offset3Clause {
return Offset3Clause(
offset(),
limit { "-1" },
this,
null,
null,
null,
null)
}
inline fun select(projection: (T, T2, T3) -> Iterable): Select3Statement {
return Select3Statement(
projection(joinOn2Clause.subject.table, joinOn2Clause.table2, table3),
this,
null,
null,
null,
null,
null,
null)
}
}
class Join4Clause(
val joinOn3Clause: JoinOn3Clause,
val table4: T4,
val type: JoinType = JoinType.INNER) {
inline fun on(condition: (T, T2, T3, T4) -> Predicate): JoinOn4Clause {
return JoinOn4Clause(
joinOn3Clause,
table4,
type,
condition(joinOn3Clause.joinOn2Clause.subject.table, joinOn3Clause.joinOn2Clause.table2, joinOn3Clause.table3, table4)
)
}
}
class JoinOn4Clause(
val joinOn3Clause: JoinOn3Clause,
val table4: T4,
val type: JoinType,
val condition: Predicate) {
inline fun where(predicate: (T, T2, T3, T4) -> Predicate): Where4Clause {
return Where4Clause(
predicate(
joinOn3Clause.joinOn2Clause.subject.table,
joinOn3Clause.joinOn2Clause.table2,
joinOn3Clause.table3,
table4
),
this)
}
inline fun groupBy(group: (T, T2, T3, T4) -> Iterable): Group4Clause {
return Group4Clause(
group(
joinOn3Clause.joinOn2Clause.subject.table,
joinOn3Clause.joinOn2Clause.table2,
joinOn3Clause.table3,
table4
),
this,
null
)
}
inline fun orderBy(order: (T, T2, T3, T4) -> Iterable): Order4Clause {
return Order4Clause(
order(
joinOn3Clause.joinOn2Clause.subject.table,
joinOn3Clause.joinOn2Clause.table2,
joinOn3Clause.table3,
table4
),
this,
null,
null,
null
)
}
inline fun limit(limit: () -> Any): Limit4Clause {
return Limit4Clause(
limit(),
this,
null,
null,
null,
null)
}
inline fun offset(offset: () -> String): Offset4Clause {
return Offset4Clause(
offset(),
limit { "-1" },
this,
null,
null,
null,
null)
}
inline fun select(projection: (T, T2, T3, T4) -> Iterable): Select4Statement {
return Select4Statement(
projection(
joinOn3Clause.joinOn2Clause.subject.table,
joinOn3Clause.joinOn2Clause.table2,
joinOn3Clause.table3,
table4
),
this,
null,
null,
null,
null,
null,
null)
}
}
enum class JoinType {
INNER,
OUTER
}
================================================
FILE: core/src/tel/egram/kuery/dml/LimitClause.kt
================================================
package tel.egram.kuery.dml
import tel.egram.kuery.*
class LimitClause(
val limit: Any,
val subject: Subject,
val whereClause: WhereClause?,
val orderClause: OrderClause?,
val groupClause: GroupClause?,
val havingClause: HavingClause?) {
inline fun offset(offset: () -> Any): OffsetClause {
return OffsetClause(
offset(),
this,
subject,
whereClause,
orderClause,
groupClause,
havingClause)
}
inline fun select(projection: (T) -> Iterable): SelectStatement {
return SelectStatement(
projection(subject.table),
subject,
whereClause,
orderClause,
this,
null,
groupClause,
havingClause)
}
}
class Limit2Clause(
val limit: Any,
val joinOn2Clause: JoinOn2Clause,
val where2Clause: Where2Clause?,
val order2Clause: Order2Clause?,
val group2Clause: Group2Clause?,
val having2Clause: Having2Clause?) {
inline fun offset(offset: () -> Any): Offset2Clause {
return Offset2Clause(
offset(),
this,
joinOn2Clause,
where2Clause,
order2Clause,
group2Clause,
having2Clause)
}
inline fun select(projection: (T, T2) -> Iterable): Select2Statement {
return Select2Statement(
projection(joinOn2Clause.subject.table, joinOn2Clause.table2),
joinOn2Clause,
where2Clause,
order2Clause,
this,
null,
group2Clause,
having2Clause)
}
}
class Limit3Clause(
val limit: Any,
val joinOn3Clause: JoinOn3Clause,
val where3Clause: Where3Clause?,
val order3Clause: Order3Clause?,
val group3Clause: Group3Clause?,
val having3Clause: Having3Clause?) {
inline fun offset(offset: () -> Any): Offset3Clause {
return Offset3Clause(
offset(),
this,
joinOn3Clause,
where3Clause,
order3Clause,
group3Clause,
having3Clause)
}
inline fun select(projection: (T, T2, T3) -> Iterable): Select3Statement {
return Select3Statement(
projection(joinOn3Clause.joinOn2Clause.subject.table, joinOn3Clause.joinOn2Clause.table2, joinOn3Clause.table3),
joinOn3Clause,
where3Clause,
order3Clause,
this,
null,
group3Clause,
having3Clause)
}
}
class Limit4Clause(
val limit: Any,
val joinOn4Clause: JoinOn4Clause,
val where4Clause: Where4Clause?,
val order4Clause: Order4Clause?,
val group4Clause: Group4Clause?,
val having4Clause: Having4Clause?) {
inline fun offset(offset: () -> Any): Offset4Clause {
return Offset4Clause(
offset(),
this,
joinOn4Clause,
where4Clause,
order4Clause,
group4Clause,
having4Clause)
}
inline fun select(projection: (T, T2, T3, T4) -> Iterable): Select4Statement {
return Select4Statement(
projection(
joinOn4Clause.joinOn3Clause.joinOn2Clause.subject.table,
joinOn4Clause.joinOn3Clause.joinOn2Clause.table2,
joinOn4Clause.joinOn3Clause.table3,
joinOn4Clause.table4
),
joinOn4Clause,
where4Clause,
order4Clause,
this,
null,
group4Clause,
having4Clause)
}
}
================================================
FILE: core/src/tel/egram/kuery/dml/OffsetClause.kt
================================================
package tel.egram.kuery.dml
import tel.egram.kuery.*
class OffsetClause(
val offset: Any,
val limit: LimitClause,
val subject: Subject,
val whereClause: WhereClause?,
val orderClause: OrderClause?,
val groupClause: GroupClause?,
val havingClause: HavingClause