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?) { inline fun select(projection: (T) -> Iterable): SelectStatement { return SelectStatement( projection(subject.table), subject, whereClause, orderClause, limit, this, groupClause, havingClause) } } class Offset2Clause( val offset: Any, val limit2Clause: Limit2Clause, val joinOn2Clause: JoinOn2Clause, val whereClause: Where2Clause?, val orderClause: Order2Clause?, val group2Clause: Group2Clause?, val having2Clause: Having2Clause?) { inline fun select(projection: (T, T2) -> Iterable): Select2Statement { return Select2Statement( projection(joinOn2Clause.subject.table, joinOn2Clause.table2), joinOn2Clause, whereClause, orderClause, limit2Clause, this, group2Clause, having2Clause) } } class Offset3Clause( val offset: Any, val limit3Clause: Limit3Clause, val joinOn3Clause: JoinOn3Clause, val where3Clause: Where3Clause?, val order3Clause: Order3Clause?, val group3Clause: Group3Clause?, val having3Clause: 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, limit3Clause, this, group3Clause, having3Clause) } } class Offset4Clause( val offset: Any, val limit4Clause: Limit4Clause, val joinOn4Clause: JoinOn4Clause, val where4Clause: Where4Clause?, val order4Clause: Order4Clause?, val group4Clause: Group4Clause?, val having4Clause: 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, limit4Clause, this, group4Clause, having4Clause) } } ================================================ FILE: core/src/tel/egram/kuery/dml/OrderClause.kt ================================================ package tel.egram.kuery.dml import tel.egram.kuery.* class OrderClause( val orderings: Iterable, val subject: Subject, val whereClause: WhereClause?, val groupClause: GroupClause?, val havingClause: HavingClause?) { inline fun limit(limit: () -> Any): LimitClause { return LimitClause( limit(), subject, whereClause, this, groupClause, havingClause) } inline fun offset(offset: () -> Any): OffsetClause { return OffsetClause( offset(), limit { "-1" }, subject, whereClause, this, groupClause, havingClause) } inline fun select(projection: (T) -> Iterable): SelectStatement { return SelectStatement( projection(subject.table), subject, whereClause, this, null, null, groupClause, havingClause) } } class Order2Clause( val orderings: Iterable, val joinOn2Clause: JoinOn2Clause, val where2Clause: Where2Clause?, val group2Clause: Group2Clause?, val having2Clause: Having2Clause?) { inline fun limit(limit: () -> Any): Limit2Clause { return Limit2Clause( limit(), joinOn2Clause, where2Clause, this, group2Clause, having2Clause) } inline fun offset(offset: () -> Any): Offset2Clause { return Offset2Clause( offset(), limit { "-1" }, joinOn2Clause, where2Clause, this, group2Clause, having2Clause) } inline fun select(projection: (T, T2) -> Iterable): Select2Statement { return Select2Statement( projection(joinOn2Clause.subject.table, joinOn2Clause.table2), joinOn2Clause, where2Clause, this, null, null, group2Clause, having2Clause) } } class Order3Clause( val orderings: Iterable, val joinOn3Clause: JoinOn3Clause, val where3Clause: Where3Clause?, val group3Clause: Group3Clause?, val having3Clause: Having3Clause?) { inline fun limit(limit: () -> Any): Limit3Clause { return Limit3Clause( limit(), joinOn3Clause, where3Clause, this, group3Clause, having3Clause) } inline fun offset(offset: () -> Any): Offset3Clause { return Offset3Clause( offset(), limit { "-1" }, joinOn3Clause, where3Clause, this, 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, this, null, null, group3Clause, having3Clause) } } class Order4Clause( val orderings: Iterable, val joinOn4Clause: JoinOn4Clause, val where4Clause: Where4Clause?, val group4Clause: Group4Clause?, val having4Clause: Having4Clause?) { inline fun limit(limit: () -> Any): Limit4Clause { return Limit4Clause( limit(), joinOn4Clause, where4Clause, this, group4Clause, having4Clause) } inline fun offset(offset: () -> Any): Offset4Clause { return Offset4Clause( offset(), limit { "-1" }, joinOn4Clause, where4Clause, this, 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, this, null, null, group4Clause, having4Clause) } } ================================================ FILE: core/src/tel/egram/kuery/dml/Ordering.kt ================================================ package tel.egram.kuery.dml interface Ordering : Iterable { val key: Any val asc: Boolean override fun iterator(): Iterator { return object : Iterator { var valid = true override fun hasNext(): Boolean { return valid } override fun next(): Ordering { valid = false return this@Ordering } } } class By(override val key: Any, override val asc: Boolean) : Ordering } ================================================ FILE: core/src/tel/egram/kuery/dml/Projection.kt ================================================ package tel.egram.kuery.dml interface Projection : Iterable { override fun iterator(): Iterator { return object : Iterator { var valid = true override fun hasNext(): Boolean { return valid } override fun next(): Projection { valid = false return this@Projection } } } } ================================================ FILE: core/src/tel/egram/kuery/dml/SelectStatement.kt ================================================ package tel.egram.kuery.dml import tel.egram.kuery.* class SelectStatement( val projection: Iterable, val subject: Subject, val whereClause: WhereClause?, val orderClause: OrderClause?, val limitClause: LimitClause?, val offsetClause: OffsetClause?, val groupClause: GroupClause?, val havingClause: HavingClause?) { fun toString(dialect: Dialect): String { return dialect.build(this) } } class Select2Statement( val projection: Iterable, val joinOn2Clause: JoinOn2Clause, val where2Clause: Where2Clause?, val order2Clause: Order2Clause?, val limit2Clause: Limit2Clause?, val offset2Clause: Offset2Clause?, val group2Clause: Group2Clause?, val having2Clause: Having2Clause?) { fun toString(dialect: Dialect): String { return dialect.build(this) } } class Select3Statement( val projection: Iterable, val joinOn3Clause: JoinOn3Clause, val where3Clause: Where3Clause?, val order3Clause: Order3Clause?, val limit3Clause: Limit3Clause?, val offset3Clause: Offset3Clause?, val group3Clause: Group3Clause?, val having3Clause: Having3Clause?) { fun toString(dialect: Dialect): String { return dialect.build(this) } } class Select4Statement( val projection: Iterable, val joinOn4Clause: JoinOn4Clause, val where4Clause: Where4Clause?, val order4Clause: Order4Clause?, val limit4Clause: Limit4Clause?, val offset4Clause: Offset4Clause?, val group4Clause: Group4Clause?, val having4Clause: Having4Clause?) { fun toString(dialect: Dialect): String { return dialect.build(this) } } ================================================ FILE: core/src/tel/egram/kuery/dml/UpdateStatement.kt ================================================ package tel.egram.kuery.dml import tel.egram.kuery.* class UpdateStatement( val assignments: Iterable, val subject: Subject, val whereClause: WhereClause?) { fun toString(dialect: Dialect): String { return dialect.build(this) } } ================================================ FILE: core/src/tel/egram/kuery/dml/WhereClause.kt ================================================ package tel.egram.kuery.dml import tel.egram.kuery.Predicate import tel.egram.kuery.Subject import tel.egram.kuery.Table class WhereClause( val predicate: Predicate, val subject: Subject) { inline fun groupBy(group: (T) -> Iterable): GroupClause { return GroupClause(group(subject.table), subject, this) } inline fun orderBy(order: (T) -> Iterable): OrderClause { return OrderClause(order(subject.table), subject, this, null, null) } inline fun limit(limit: () -> Any): LimitClause { return LimitClause( limit(), subject, this, null, null, null) } inline fun offset(offset: () -> Any): OffsetClause { return OffsetClause( offset(), limit { "-1" }, subject, this, null, null, null) } inline fun select(projection: (T) -> Iterable): SelectStatement { return SelectStatement( projection(subject.table), subject, this, null, null, null, null, null ) } inline fun selectAll(): SelectStatement { return SelectStatement( listOf(), subject, this, null, null, null, null, null ) } inline fun update(value: (T) -> Iterable): UpdateStatement { return UpdateStatement(value(subject.table), subject, this) } inline fun delete(): DeleteStatement { return DeleteStatement(subject, this) } } class Where2Clause( val predicate: Predicate, val joinOn2Clause: JoinOn2Clause) { inline fun groupBy(group: (T, T2) -> Iterable): Group2Clause { return Group2Clause(group(joinOn2Clause.subject.table, joinOn2Clause.table2), joinOn2Clause, this) } inline fun orderBy(order: (T, T2) -> Iterable): Order2Clause { return Order2Clause(order(joinOn2Clause.subject.table, joinOn2Clause.table2), joinOn2Clause, this, null, null) } inline fun limit(limit: () -> Any): Limit2Clause { return Limit2Clause( limit(), joinOn2Clause, this, null, null, null) } inline fun offset(offset: () -> Any): Offset2Clause { return Offset2Clause( offset(), limit { "-1" }, joinOn2Clause, this, null, null, null) } inline fun select(projection: (T, T2) -> Iterable): Select2Statement { return Select2Statement( projection(joinOn2Clause.subject.table, joinOn2Clause.table2), joinOn2Clause, this, null, null, null, null, null ) } } class Where3Clause( val predicate: Predicate, val joinOn3Clause: JoinOn3Clause) { inline fun groupBy(group: (T, T2, T3) -> Iterable): Group3Clause { return Group3Clause( group(joinOn3Clause.joinOn2Clause.subject.table, joinOn3Clause.joinOn2Clause.table2, joinOn3Clause.table3), joinOn3Clause, this) } inline fun orderBy(order: (T, T2, T3) -> Iterable): Order3Clause { return Order3Clause( order(joinOn3Clause.joinOn2Clause.subject.table, joinOn3Clause.joinOn2Clause.table2, joinOn3Clause.table3), joinOn3Clause, this, null, null) } inline fun limit(limit: () -> Any): Limit3Clause { return Limit3Clause( limit(), joinOn3Clause, this, null, null, null) } inline fun offset(offset: () -> Any): Offset3Clause { return Offset3Clause( offset(), limit { "-1" }, joinOn3Clause, this, null, null, null) } inline fun select(projection: (T, T2, T3) -> Iterable): Select3Statement { return Select3Statement( projection( joinOn3Clause.joinOn2Clause.subject.table, joinOn3Clause.joinOn2Clause.table2, joinOn3Clause.table3 ), joinOn3Clause, this, null, null, null, null, null ) } } class Where4Clause( val predicate: Predicate, val joinOn4Clause: JoinOn4Clause) { inline fun groupBy(group: (T, T2, T3, T4) -> Iterable): Group4Clause { return Group4Clause( group( joinOn4Clause.joinOn3Clause.joinOn2Clause.subject.table, joinOn4Clause.joinOn3Clause.joinOn2Clause.table2, joinOn4Clause.joinOn3Clause.table3, joinOn4Clause.table4 ), joinOn4Clause, this) } 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, this, null, null) } inline fun limit(limit: () -> Any): Limit4Clause { return Limit4Clause( limit(), joinOn4Clause, this, null, null, null) } inline fun offset(offset: () -> Any): Offset4Clause { return Offset4Clause( offset(), limit { "-1" }, joinOn4Clause, this, null, null, 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, this, null, null, null, null, null ) } } ================================================ FILE: gradle/wrapper/gradle-wrapper.properties ================================================ #Mon Oct 19 12:09:08 BRST 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-all.zip ================================================ FILE: gradle.properties ================================================ # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # The Gradle daemon aims to improve the startup and execution time of Gradle. # When set to true the Gradle daemon is to run the build. # org.gradle.daemon=true # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx10248m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true # Enables new incubating mode that makes Gradle selective when configuring projects. # Only relevant projects are configured which results in faster builds for large multi-projects. # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:configuration_on_demand # org.gradle.configureondemand=true ================================================ FILE: gradlew ================================================ #!/usr/bin/env bash ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn ( ) { echo "$*" } die ( ) { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; esac # For Cygwin, ensure paths are in UNIX format before anything is touched. if $cygwin ; then [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` fi # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >&- APP_HOME="`pwd -P`" cd "$SAVED" >&- CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules function splitJvmOpts() { JVM_OPTS=("$@") } eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" ================================================ FILE: gradlew.bat ================================================ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: sample-maven.properties ================================================ bintray_user=user bintray_apikey=a9a9a9a9a9a9a9a9a9a99a9a9a9a99a9a9 bintray_repo=https://dl.bintray.com/user/maven/ ================================================ FILE: settings.gradle ================================================ include ':core', ':sqlite' ================================================ FILE: sqlite/build.gradle ================================================ apply plugin: 'kotlin' apply from: "${rootProject.rootDir}/bintray.gradle" sourceSets { main.kotlin.srcDirs += 'src' test.kotlin.srcDirs += 'test' } dependencies { compile project(':core') compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile 'junit:junit:4.12' compile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version" } ================================================ FILE: sqlite/src/tel/egram/kuery/sqlite/SQLiteDefinition.kt ================================================ package tel.egram.kuery.sqlite import tel.egram.kuery.* import tel.egram.kuery.ddl.* class SQLiteDefinition(column: Table.Column, val meta: SQLiteDefinition.Meta) : Definition.Column(column, meta.type) { fun primaryKey(autoIncrement: Boolean = false): SQLiteDefinition { if (autoIncrement && meta.type != "INTEGER") throw UnsupportedOperationException("Autoincrement is only supported on INTEGER columns") return SQLiteDefinition(column, meta.copy(primaryKeyConstraint = PrimaryKeyConstraint(autoIncrement))) } fun foreignKey(references: Table.Column): SQLiteDefinition { return SQLiteDefinition(column, meta.copy(foreignKeyConstraint = ForeignKeyConstraint(references))) } fun unique(): SQLiteDefinition { return SQLiteDefinition(column, meta.copy(uniqueConstraint = UniqueConstraint())) } fun notNull(): SQLiteDefinition { return SQLiteDefinition(column, meta.copy(notNullConstraint = NotNullConstraint())) } data class Meta( val type: String, val primaryKeyConstraint: PrimaryKeyConstraint? = null, val foreignKeyConstraint: ForeignKeyConstraint? = null, val uniqueConstraint: UniqueConstraint? = null, val notNullConstraint: NotNullConstraint? = null ) class PrimaryKeyConstraint(val autoIncrement: Boolean = false) class ForeignKeyConstraint(val references: Table.Column) class UniqueConstraint class NotNullConstraint } fun integer(column: Table.Column): SQLiteDefinition { return SQLiteDefinition(column, SQLiteDefinition.Meta(type = "INTEGER")) } fun real(column: Table.Column): SQLiteDefinition { return SQLiteDefinition(column, SQLiteDefinition.Meta(type = "REAL")) } fun text(column: Table.Column): SQLiteDefinition { return SQLiteDefinition(column, SQLiteDefinition.Meta(type = "TEXT")) } fun blob(column: Table.Column): SQLiteDefinition { return SQLiteDefinition(column, SQLiteDefinition.Meta(type = "BLOB")) } ================================================ FILE: sqlite/src/tel/egram/kuery/sqlite/SQLiteDialect.kt ================================================ package tel.egram.kuery.sqlite import tel.egram.kuery.* import tel.egram.kuery.ddl.CreateTableStatement import tel.egram.kuery.ddl.DropTableStatement import tel.egram.kuery.dml.* object SQLiteDialect : Dialect { override fun build(statement: CreateTableStatement): String { val builder = StringBuilder() builder.append("CREATE TABLE ") appendTableName(builder, statement.subject.table) builder.append('(') var delim = "" for (definition in statement.definitions) { builder.append(delim) delim = ", " appendShortColumnName(builder, definition.column) builder.append(' ') builder.append(definition.type) if (definition is SQLiteDefinition) { if (definition.meta.primaryKeyConstraint != null) { builder.append(" PRIMARY KEY") if (definition.meta.primaryKeyConstraint.autoIncrement) builder.append(" AUTOINCREMENT") } if (definition.meta.foreignKeyConstraint != null) { builder.append(" REFERENCES ") appendFullColumnName(builder, definition.meta.foreignKeyConstraint.references) } if (definition.meta.uniqueConstraint != null) { builder.append(" UNIQUE") } if (definition.meta.notNullConstraint != null) { builder.append(" NOT NULL") } } } builder.append(')') return builder.toString() } override fun build(statement: DropTableStatement): String { return "DROP TABLE \"${statement.subject.table}\"" } override fun build(statement: SelectStatement): String { val builder = StringBuilder() builder.append("SELECT ") appendProjection(builder, statement.projection, false) builder.append(" FROM ") appendTableName(builder, statement.subject.table) val where = statement.whereClause if (where != null) { builder.append(" WHERE ") appendPredicate(builder, where.predicate, false) } val group = statement.groupClause if (group != null) { builder.append(" GROUP BY ") appendProjection(builder, group.projection, false) } val having = statement.havingClause if (having != null) { builder.append(" HAVING ") appendPredicate(builder, having.predicate, false) } val order = statement.orderClause if (order != null) { builder.append(" ORDER BY ") appendOrdering(builder, order.orderings, false) } val limit = statement.limitClause if (limit != null) { builder.append(" LIMIT ") builder.append(limit.limit) } val offset = statement.offsetClause if (offset != null) { builder.append(" OFFSET ") builder.append(offset.offset) } return builder.toString() } override fun build(statement: Select2Statement): String { val builder = StringBuilder() builder.append("SELECT ") appendProjection(builder, statement.projection, true) builder.append(" FROM ") appendTableName(builder, statement.joinOn2Clause.subject.table) if (statement.joinOn2Clause.type == JoinType.OUTER) builder.append(" OUTER") builder.append(" JOIN ") appendTableName(builder, statement.joinOn2Clause.table2) builder.append(" ON ") appendPredicate(builder, statement.joinOn2Clause.condition, true) val where = statement.where2Clause if (where != null) { builder.append(" WHERE ") appendPredicate(builder, where.predicate, true) } val group = statement.group2Clause if (group != null) { builder.append(" GROUP BY ") appendProjection(builder, group.projection, true) } val having = statement.having2Clause if (having != null) { builder.append(" HAVING ") appendPredicate(builder, having.predicate, true) } val order = statement.order2Clause if (order != null) { builder.append(" ORDER BY ") appendOrdering(builder, order.orderings, true) } val limit = statement.limit2Clause if (limit != null) { builder.append(" LIMIT ") builder.append(limit.limit) } val offset = statement.offset2Clause if (offset != null) { builder.append(" OFFSET ") builder.append(offset.offset) } return builder.toString() } override fun build(statement: Select3Statement): String { val builder = StringBuilder() builder.append("SELECT ") appendProjection(builder, statement.projection, true) builder.append(" FROM ") appendTableName(builder, statement.joinOn3Clause.joinOn2Clause.subject.table) if (statement.joinOn3Clause.joinOn2Clause.type == JoinType.OUTER) builder.append(" OUTER") builder.append(" JOIN ") appendTableName(builder, statement.joinOn3Clause.joinOn2Clause.table2) builder.append(" ON ") appendPredicate(builder, statement.joinOn3Clause.joinOn2Clause.condition, true) if (statement.joinOn3Clause.type == JoinType.OUTER) builder.append(" OUTER") builder.append(" JOIN ") appendTableName(builder, statement.joinOn3Clause.table3) builder.append(" ON ") appendPredicate(builder, statement.joinOn3Clause.condition, true) val where = statement.where3Clause if (where != null) { builder.append(" WHERE ") appendPredicate(builder, where.predicate, true) } val group = statement.group3Clause if (group != null) { builder.append(" GROUP BY ") appendProjection(builder, group.projection, true) } val having = statement.having3Clause if (having != null) { builder.append(" HAVING ") appendPredicate(builder, having.predicate, true) } val order = statement.order3Clause if (order != null) { builder.append(" ORDER BY ") appendOrdering(builder, order.orderings, true) } val limit = statement.limit3Clause if (limit != null) { builder.append(" LIMIT ") builder.append(limit.limit) } val offset = statement.offset3Clause if (offset != null) { builder.append(" OFFSET ") builder.append(offset.offset) } return builder.toString() } override fun build(statement: Select4Statement): String { val builder = StringBuilder() builder.append("SELECT ") appendProjection(builder, statement.projection, true) builder.append(" FROM ") appendTableName(builder, statement.joinOn4Clause.joinOn3Clause.joinOn2Clause.subject.table) if (statement.joinOn4Clause.joinOn3Clause.joinOn2Clause.type == JoinType.OUTER) builder.append(" OUTER") builder.append(" JOIN ") appendTableName(builder, statement.joinOn4Clause.joinOn3Clause.joinOn2Clause.table2) builder.append(" ON ") appendPredicate(builder, statement.joinOn4Clause.joinOn3Clause.joinOn2Clause.condition, true) if (statement.joinOn4Clause.joinOn3Clause.type == JoinType.OUTER) builder.append(" OUTER") builder.append(" JOIN ") appendTableName(builder, statement.joinOn4Clause.joinOn3Clause.table3) builder.append(" ON ") appendPredicate(builder, statement.joinOn4Clause.joinOn3Clause.condition, true) if (statement.joinOn4Clause.type == JoinType.OUTER) builder.append(" OUTER") builder.append(" JOIN ") appendTableName(builder, statement.joinOn4Clause.table4) builder.append(" ON ") appendPredicate(builder, statement.joinOn4Clause.condition, true) val where = statement.where4Clause if (where != null) { builder.append(" WHERE ") appendPredicate(builder, where.predicate, true) } val group = statement.group4Clause if (group != null) { builder.append(" GROUP BY ") appendProjection(builder, group.projection, true) } val having = statement.having4Clause if (having != null) { builder.append(" HAVING ") appendPredicate(builder, having.predicate, true) } val order = statement.order4Clause if (order != null) { builder.append(" ORDER BY ") appendOrdering(builder, order.orderings, true) } val limit = statement.limit4Clause if (limit != null) { builder.append(" LIMIT ") builder.append(limit.limit) } val offset = statement.offset4Clause if (offset != null) { builder.append(" OFFSET ") builder.append(offset.offset) } return builder.toString() } override fun build(statement: InsertStatement): String { val builder = StringBuilder() builder.append("INSERT INTO ") appendTableName(builder, statement.subject.table) builder.append(" (") var delim = "" for (assign in statement.assignments) { builder.append(delim) delim = ", " appendShortColumnName(builder, assign.column) } builder.append(") VALUES (") delim = "" for (assign in statement.assignments) { builder.append(delim) delim = ", " appendValue(builder, assign.value) } builder.append(")") return builder.toString() } override fun build(statement: UpdateStatement): String { val builder = StringBuilder() builder.append("UPDATE ") appendTableName(builder, statement.subject.table) builder.append(" SET ") var delim = "" for (assign in statement.assignments) { builder.append(delim) delim = ", " appendShortColumnName(builder, assign.column) builder.append(" = ") appendValue(builder, assign.value) } val where = statement.whereClause if (where != null) { builder.append(" WHERE ") appendPredicate(builder, where.predicate, false) } return builder.toString() } override fun build(statement: DeleteStatement): String { val builder = StringBuilder() builder.append("DELETE FROM ") appendTableName(builder, statement.subject.table) val where = statement.whereClause if (where != null) { builder.append(" WHERE ") appendPredicate(builder, where.predicate, false) } return builder.toString() } private fun appendPredicate(builder: StringBuilder, value: Any?, fullFormat: Boolean = true) { when (value) { is Table.Column -> if (fullFormat) appendFullColumnName(builder, value) else appendShortColumnName(builder, value) is NotExpression -> { builder.append("(NOT ") appendPredicate(builder, value.param, fullFormat) builder.append(")") } is AndExpression -> { builder.append('(') appendPredicate(builder, value.left, fullFormat) builder.append(" AND ") appendPredicate(builder, value.right, fullFormat) builder.append(')') } is OrExpression -> { builder.append('(') appendPredicate(builder, value.left, fullFormat) builder.append(" OR ") appendPredicate(builder, value.right, fullFormat) builder.append(')') } is EqExpression -> { builder.append('(') if (value.right != null) { appendPredicate(builder, value.left, fullFormat) builder.append(" = ") appendPredicate(builder, value.right, fullFormat) } else { appendPredicate(builder, value.left, fullFormat) builder.append(" IS NULL") } builder.append(')') } is NeExpression -> { builder.append('(') if (value.right != null) { appendPredicate(builder, value.left, fullFormat) builder.append(" != ") appendPredicate(builder, value.right, fullFormat) } else { appendPredicate(builder, value.left, fullFormat) builder.append(" IS NOT NULL") } builder.append(')') } is LtExpression -> { builder.append('(') appendPredicate(builder, value.left, fullFormat) builder.append(" < ") appendPredicate(builder, value.right, fullFormat) builder.append(')') } is LteExpression -> { builder.append('(') appendPredicate(builder, value.left, fullFormat) builder.append(" <= ") appendPredicate(builder, value.right, fullFormat) builder.append(')') } is GtExpression -> { builder.append('(') appendPredicate(builder, value.left, fullFormat) builder.append(" > ") appendPredicate(builder, value.right, fullFormat) builder.append(')') } is GteExpression -> { builder.append('(') appendPredicate(builder, value.left, fullFormat) builder.append(" >= ") appendPredicate(builder, value.right, fullFormat) builder.append(')') } else -> appendValue(builder, value) } } private fun appendProjection(builder: StringBuilder, projection: Iterable, fullFormat: Boolean) { if ("SELECT".contentEquals(builder.toString().trim()) and projection.none()) { builder.append("*") } else { var delim = "" for (proj in projection) { builder.append(delim) delim = ", " if (proj is Table.Column) { if (fullFormat) { appendFullColumnName(builder, proj) } else { appendShortColumnName(builder, proj) } } else { builder.append(proj) } } } } private fun appendOrdering(builder: StringBuilder, orderings: Iterable, fullFormat: Boolean) { var delim = "" for (order in orderings) { builder.append(delim) delim = ", " if (order.key is Table.Column) { if (fullFormat) { appendFullColumnName(builder, order.key as Table.Column) } else { appendShortColumnName(builder, order.key as Table.Column) } } else { builder.append(order.key) } builder.append(if (order.asc) " ASC" else " DESC") } } private fun appendTableName(builder: StringBuilder, table: Table) { builder.append("\"$table\"") } private fun appendShortColumnName(builder: StringBuilder, column: Table.Column) { builder.append("\"$column\"") } private fun appendFullColumnName(builder: StringBuilder, column: Table.Column) { builder.append("\"${column.table}\".\"$column\"") } private fun appendValue(builder: StringBuilder, value: Any?) { value?.let { builder.append((value as? String)?.escapedSQLString() ?: value) } ?: builder.append("NULL") } private fun String.escapedSQLString(): String = "\'${this.replace("'", "''")}\'" } ================================================ FILE: sqlite/test/tel/egram/kuery/sqlite/tests/SQLiteDialectTest.kt ================================================ package tel.egram.kuery.sqlite.tests import tel.egram.kuery.* import tel.egram.kuery.sqlite.* import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 import kotlin.test.assertEquals @RunWith(JUnit4::class) class SQLiteDialectTest { private object TestTable : Table("TestTable") { val id = Column("id") val component1 = Column("component1") val component2 = Column("component2") } @Test fun `test create table`() { val expected = "CREATE TABLE \"TestTable\"(\"id\" INTEGER PRIMARY KEY AUTOINCREMENT, \"component1\" INTEGER NOT NULL, \"component2\" TEXT NOT NULL)" val result = over(TestTable) .create { integer(TestTable.id).primaryKey(autoIncrement = true).. integer(TestTable.component1).notNull().. text(TestTable.component2).notNull() }.toString(SQLiteDialect) assertEquals(expected, result) } @Test fun `test where with Strings`() { val expected = "SELECT \"component1\", \"component2\" FROM \"TestTable\" WHERE ((\"component1\" = 1) AND (\"component2\" = 'TEST'))" val result = from(TestTable).where { (it.component1 eq 1) and (it.component2 eq "TEST") }.select { it.component1..it.component2 }.toString(SQLiteDialect) assertEquals(expected, result) } @Test fun `test where with Strings containing single and double quotes`() { val expectedSingle = "SELECT \"component1\", \"component2\" FROM \"TestTable\" WHERE ((\"component1\" = 1) AND (\"component2\" = 'T''EST'))" val resultSingle = from(TestTable).where { (it.component1 eq 1) and (it.component2 eq "T'EST") }.select { it.component1..it.component2 }.toString(SQLiteDialect) assertEquals(expectedSingle, resultSingle) val expectedDouble = "SELECT \"component1\", \"component2\" FROM \"TestTable\" WHERE ((\"component1\" = 1) AND (\"component2\" = 'T\"EST'))" val resultDouble = from(TestTable).where { (it.component1 eq 1) and (it.component2 eq "T\"EST") }.select { it.component1..it.component2 }.toString(SQLiteDialect) assertEquals(expectedDouble, resultDouble) } }