Skip to content

Commit

Permalink
Update readme (medly#37)
Browse files Browse the repository at this point in the history
* Ignore .idea folder

* Bump org.jetbrains.kotlin.jvm from 1.3.61 to 1.3.70 (medly#14)

Bumps org.jetbrains.kotlin.jvm from 1.3.61 to 1.3.70.

Signed-off-by: dependabot-preview[bot] <[email protected]>

* (medly#4) Allowing nullable params for batchExecuteCommand (medly#18)

* - parameterMetaData.getParameterClassName returning null (medly#19)

- remove unused params from ParamModel
- add test for jsonb along with array

* Bump org.jetbrains.kotlin.jvm from 1.3.70 to 1.3.72 (medly#24)

Bumps org.jetbrains.kotlin.jvm from 1.3.70 to 1.3.72.

Signed-off-by: dependabot-preview[bot] <[email protected]>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>

* Bump postgresql from 42.2.9 to 42.2.12 (medly#22)

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.2.9 to 42.2.12.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](pgjdbc/pgjdbc@REL42.2.9...REL42.2.12)

Signed-off-by: dependabot-preview[bot] <[email protected]>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>

* Bump postgresql from 1.12.5 to 1.14.0 (medly#23)

Bumps [postgresql](https://github.com/testcontainers/testcontainers-java) from 1.12.5 to 1.14.0.
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/master/CHANGELOG.md)
- [Commits](testcontainers/testcontainers-java@1.12.5...1.14.0)

Signed-off-by: dependabot-preview[bot] <[email protected]>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>

* Bump postgresql from 1.14.0 to 1.14.3 (medly#31)

Bumps [postgresql](https://github.com/testcontainers/testcontainers-java) from 1.14.0 to 1.14.3.
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/master/CHANGELOG.md)
- [Commits](testcontainers/testcontainers-java@1.14.0...1.14.3)

Signed-off-by: dependabot-preview[bot] <[email protected]>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>

* Bump kotlinpoet from 1.5.0 to 1.6.0 (medly#30)

Bumps [kotlinpoet](https://github.com/square/kotlinpoet) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/square/kotlinpoet/releases)
- [Changelog](https://github.com/square/kotlinpoet/blob/master/CHANGELOG.md)
- [Commits](square/kotlinpoet@1.5.0...1.6.0)

Signed-off-by: dependabot-preview[bot] <[email protected]>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>

* issue#26 | Allowing params class to not have any fields (medly#27)

* Making fields in result nullable depending on how they are defined in schema (medly#33)

* Bump postgresql from 42.2.12 to 42.2.13 (medly#32)

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.2.12 to 42.2.13.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](pgjdbc/pgjdbc@REL42.2.12...REL42.2.13)

Signed-off-by: dependabot-preview[bot] <[email protected]>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>

* Bump postgresql from 42.2.13 to 42.2.14 (medly#34)

Bumps [postgresql](https://github.com/pgjdbc/pgjdbc) from 42.2.13 to 42.2.14.
- [Release notes](https://github.com/pgjdbc/pgjdbc/releases)
- [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md)
- [Commits](pgjdbc/pgjdbc@REL42.2.13...REL42.2.14)

Signed-off-by: dependabot-preview[bot] <[email protected]>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>

* Add getting stared documentation | Ignore out folders frmo git

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Bhimsen Padalkar <[email protected]>
Co-authored-by: Swanand Keskar <[email protected]>
  • Loading branch information
4 people authored Jun 12, 2020
1 parent f1601c2 commit 5f0bf7d
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Ignore Gradle project-specific cache directory
.gradle
.idea

# Ignore Gradle build output directory
build

**/out/*
183 changes: 182 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,182 @@
## Norm (Proof of Concept)
## Norm

## Table of Contents
- [Concept](#concept)
- [Design](#design)
- [codegen](#codegen)
- [runtime](#runtime)
- [Getting Started](#getting-started)

### Concept:

**Norm(No-ORM)**, as the name suggests, is a library whose idealogy is opposite to that of how standard ORMs work. Norm is designed to avoid two things:
1. Having to write entity, query and result/response classes by hand
2. Writing queries/commands which would throw syntax or semantic errors at runtime


### Design:

It is a library for Kotlin and postgres which enables generating query/command classes at compile time if the query is syntactically and semantically right, and provides methods to execute them on runtime.

Hence, Norm has two packages:

1. ### **codegen**
Given a postgres sql query or command in the form of a .sql file, this package generates a query class, params class, paramSetter class and resultMapper class in Kotlin.

#### How it works:

a. It needs a postgres connection

b. Analyzes the sql file by creating a [PreparedStatement](https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html)

c. If no database errors, creates a [SqlModel](https://github.com/medly/norm/blob/master/codegen/src/main/kotlin/norm/SqlAnalyzer.kt) which acts as an input to CodeGenerator

d. Kotlin file with classes of Query or Command, ParamSetter and RowMapper are generated from SqlModel


2. ### **runtime**

#### What it does:

a. Provides [interfaces](https://github.com/medly/norm/blob/master/runtime/src/main/kotlin/norm/TypedSqlExtensions.kt) which are super types for all query, command, params, row mapper classes.

b. Provides multiple [functions](https://github.com/medly/norm/blob/master/runtime/src/main/kotlin/norm/SqlExtensions.kt) on these interfaces to be able to execute query/command, map result to a list, execute batch commands and queries etc.

These methods run against a [Connection](https://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html) or on a [ResultSet](https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html) or on a [PreparedStatement](https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html).

### Getting Started:
1. Setup
- Start postgres server locally
- Add norm dependencies
````
configurations {
norm
}
dependencies {
implementation "org.postgresql:postgresql:$postgresVersion"
norm 'com.github.medly.norm:codegen:$normVersion'
norm 'com.github.medly.norm:runtime:$normVersion'
}
*Pre-requisites*: kotlin dependencies
2. Schema and table creation
- Create schemas and tables needed for your application or repository.
- Lets take example of a ```person table``` and create it in the default ```public schema``` of default ```postgres database```
```
psql -p 5432 -d postgres
postgres=# create table persons(
id SERIAL PRIMARY KEY,
name VARCHAR,
age INT,
occupation VARCHAR,
address VARCHAR
);
```
- All or any table creations and migrations need to be run before using norm to generate classes
3. Writing query/command and generating classes using norm
- norm needs paths to two folders defined:
1. input source directory - contains all sql files
2. output source directory - would contain all files generated by norm
- add a task in gradle which would execute norm's code generation
```
task compileNorm(type: JavaExec) {
classpath = configurations.norm
main = "norm.MainKt"
args "${rootProject.rootDir}/sql" //input dir
args "${rootProject.rootDir}/gen" //output dir
args "jdbc:postgresql://localhost/postgres" //postgres connection string with db name
args "postgres" //db username
args "" //db password (optional for local)
}
```
- write a query eg that fetches all persons whose age is greater than some number
- add a folder in sql folder, say eg ```person```
- add a sql file in this folder with name, say eg ```get-all-persons-above-given-age```
```SELECT * FROM persons WHERE AGE > :age;```
- run ```./gradlew compileNorm```. It will generate a folder within ```gen``` (output dir) with the same name as folder inside ```sql```(input dir), ```person```.
The generated classes would be within a file named - ```GetAllPersonsAboveGivenAge``` (title case name of sql file)
The content of generated file would look like:
```
package person
import java.sql.PreparedStatement
import java.sql.ResultSet
import kotlin.Int
import kotlin.String
import norm.ParamSetter
import norm.Query
import norm.RowMapper
data class GetAllPersonsAboveGivenAgeParams(
val age: Int?
)
class GetAllPersonsAboveGivenAgeParamSetter : ParamSetter<GetAllPersonsAboveGivenAgeParams> {
override fun map(ps: PreparedStatement, params: GetAllPersonsAboveGivenAgeParams) {
ps.setObject(1, params.age)
}
}
data class GetAllPersonsAboveGivenAgeResult(
val id: Int,
val name: String?,
val age: Int?,
val occupation: String?,
val address: String?
)
class GetAllPersonsAboveGivenAgeRowMapper : RowMapper<GetAllPersonsAboveGivenAgeResult> {
override fun map(rs: ResultSet): GetAllPersonsAboveGivenAgeResult =
GetAllPersonsAboveGivenAgeResult(
id = rs.getObject("id") as kotlin.Int,
name = rs.getObject("name") as kotlin.String?,
age = rs.getObject("age") as kotlin.Int?,
occupation = rs.getObject("occupation") as kotlin.String?,
address = rs.getObject("address") as kotlin.String?)
}
class GetAllPersonsAboveGivenAgeQuery : Query<GetAllPersonsAboveGivenAgeParams,
GetAllPersonsAboveGivenAgeResult> {
override val sql: String = """
|SELECT * FROM persons WHERE AGE > ?;
|""".trimMargin()
override val mapper: RowMapper<GetAllPersonsAboveGivenAgeResult> =
GetAllPersonsAboveGivenAgeRowMapper()
override val paramSetter: ParamSetter<GetAllPersonsAboveGivenAgeParams> =
GetAllPersonsAboveGivenAgeParamSetter()
}
```
4. Executing queries/commands using norm
- To run any query/command, a DataSource connection of postgres is required.
- Create an instance of DataSource using the postgresql driver(already added in dependency) methods
```
val dataSource = PGSimpleDataSource().also {
it.setUrl("jdbc:postgresql://localhost/postgres")
it.user = "postgres"
it.password = ""
}
```
- Execute the query:
```
val result = dataSource.connection.use { connection ->
GetAllPersonsAboveGivenAgeQuery().query(connection, GetAllPersonsAboveGivenAgeParams(20))
}
result.map { res ->
println(res.id)
println(res.name)
println(res.age)
println(res.occupation)
println(res.address)
}
```
2 changes: 1 addition & 1 deletion codegen/src/test/resources/init_postgres.sql
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ CREATE TABLE owners(
id serial PRIMARY KEY,
colors varchar[],
details jsonb
)
);

0 comments on commit 5f0bf7d

Please sign in to comment.