diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index fdc392fe..d2ce72d1 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -16,5 +16,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 00000000..2b63946d
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 6c26f07e..eed9d93f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -5,6 +5,11 @@ plugins {
// https://kotlinlang.org/docs/releases.html#release-details
kotlin("jvm") version "1.9.20"
id("org.jmailen.kotlinter") version "3.12.0"
+
+ // SQLDelight - Generates typesafe Kotlin APIs from SQL
+ // https://cashapp.github.io/sqldelight/2.0.0/
+ id("app.cash.sqldelight") version "2.0.0"
+
// https://kotlinlang.org/docs/ksp-quickstart.html#use-your-own-processor-in-a-project
// id("com.google.devtools.ksp") version "1.9.20-1.0.6" // Not needed yet.
application
@@ -14,9 +19,23 @@ group = "dev.hossain.githubstats"
version = "1.0-SNAPSHOT"
repositories {
+ google()
mavenCentral()
}
+// SQLDelight - Generates typesafe Kotlin APIs from SQL
+// https://github.com/cashapp/sqldelight
+sqldelight {
+ databases {
+ create("GitHubApiCacheDb") {
+ packageName.set("dev.hossain.githubstats")
+ // https://cashapp.github.io/sqldelight/2.0.0/jvm_postgresql/
+ dialect("app.cash.sqldelight:postgresql-dialect:2.0.0")
+
+ }
+ }
+}
+
dependencies {
// https://github.com/Kotlin/kotlinx.coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
@@ -45,6 +64,22 @@ dependencies {
implementation("com.squareup.moshi:moshi-adapters:1.14.0")
// ksp("com.squareup.moshi:moshi-kotlin-codegen:1.14.0") // Not needed yet.
+ // https://mvnrepository.com/artifact/org.postgresql/postgresql
+ implementation("org.postgresql:postgresql:42.6.0")
+
+ // https://mvnrepository.com/artifact/org.slf4j/slf4j-api
+ implementation("org.slf4j:slf4j-api:2.0.9")
+ // https://mvnrepository.com/artifact/org.slf4j/slf4j-simple
+ implementation("org.slf4j:slf4j-simple:2.0.9")
+
+ // 光 HikariCP・A solid, high-performance, JDBC connection pool at last.
+ // https://github.com/brettwooldridge/HikariCP#artifacts
+ // https://www.baeldung.com/hikaricp
+ implementation("com.zaxxer:HikariCP:5.0.1")
+
+ // https://cashapp.github.io/sqldelight/2.0.0/jvm_postgresql
+ implementation("app.cash.sqldelight:jdbc-driver:2.0.0")
+
// https://github.com/doyaaaaaken/kotlin-csv
implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.8.0") //for JVM platform
diff --git a/src/main/kotlin/TestDb.kt b/src/main/kotlin/TestDb.kt
new file mode 100644
index 00000000..e1eb4321
--- /dev/null
+++ b/src/main/kotlin/TestDb.kt
@@ -0,0 +1,48 @@
+import app.cash.sqldelight.db.SqlDriver
+import app.cash.sqldelight.driver.jdbc.asJdbcDriver
+import com.zaxxer.hikari.HikariConfig
+import com.zaxxer.hikari.HikariDataSource
+import dev.hossain.githubstats.GitHubApiCacheDb
+import dev.hossain.githubstats.util.LocalProperties
+import javax.sql.DataSource
+
+fun main() {
+ val newDataSource = getDataSource()
+ val newDriver: SqlDriver = newDataSource.asJdbcDriver()
+
+ doDatabaseThings(newDriver)
+}
+
+/**
+ * Creates a [DataSource] using [HikariDataSource].
+ */
+private fun getDataSource(): DataSource {
+ val properties = LocalProperties()
+ val dbHost = properties.getProperty("db_host")
+ val dbPort = properties.getProperty("db_port")
+ val dbName = properties.getProperty("db_name")
+ val userName = properties.getProperty("db_username")
+ val dbPassword = properties.getProperty("db_password")
+
+ // https://jdbc.postgresql.org/documentation/use/
+ val config = HikariConfig().apply {
+ jdbcUrl = "jdbc:postgresql://${dbHost}:${dbPort}/${dbName}"
+ driverClassName = "org.postgresql.Driver"
+ username = userName
+ password = dbPassword
+ maximumPoolSize = 3
+ isAutoCommit = false
+ transactionIsolation = "TRANSACTION_REPEATABLE_READ"
+ validate()
+ }
+ return HikariDataSource(config)
+}
+
+fun doDatabaseThings(driver: SqlDriver) {
+ val database = GitHubApiCacheDb(driver)
+ val responseCacheQueries = database.responseCacheQueries
+
+ responseCacheQueries.selectAll()
+ println(responseCacheQueries.selectAll().executeAsList())
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/dev/hossain/githubstats/io/Client.kt b/src/main/kotlin/dev/hossain/githubstats/io/Client.kt
index 8d39e1af..4b2dec71 100644
--- a/src/main/kotlin/dev/hossain/githubstats/io/Client.kt
+++ b/src/main/kotlin/dev/hossain/githubstats/io/Client.kt
@@ -20,6 +20,7 @@ import okhttp3.Cache
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient
+import okhttp3.ResponseBody
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
@@ -78,6 +79,18 @@ object Client {
chain.proceed(requestBuilder.build())
}
+ // Add another interceptor for caching
+ builder.addInterceptor { chain ->
+ println("Intercepting request: ${chain.request().url}")
+ val originalRequest = chain.request()
+
+ val response = chain.proceed(originalRequest)
+ val responseBody: String = response.peekBody(Long.MAX_VALUE).string()
+ println("Response body size: ${responseBody.length}")
+
+ response
+ }
+
// https://square.github.io/okhttp/features/caching/
builder.cache(
Cache(
diff --git a/src/main/resources/strings.properties b/src/main/resources/strings.properties
index c537b5a2..d66afae7 100644
--- a/src/main/resources/strings.properties
+++ b/src/main/resources/strings.properties
@@ -4,7 +4,9 @@
# ---------------------------------------------------------------------------------------------------------------------
# This only supports ISO 8859-1 character encoding
# -- Why? See: https://stackoverflow.com/a/59479929/132121
+#
# Need special UTF-8 unicode char, see https://www.fileformat.info/info/unicode/char/search.htm
+#
# Need formatting help? See
# -- https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax
# -- https://docs.oracle.com/javase/tutorial/java/data/numberformat.html
diff --git a/src/main/sqldelight/dev/hossain/githubstats/Player.sq b/src/main/sqldelight/dev/hossain/githubstats/Player.sq
new file mode 100644
index 00000000..5a054671
--- /dev/null
+++ b/src/main/sqldelight/dev/hossain/githubstats/Player.sq
@@ -0,0 +1,21 @@
+CREATE TABLE hockeyPlayer (
+ player_number INTEGER PRIMARY KEY NOT NULL,
+ full_name TEXT NOT NULL
+);
+
+CREATE INDEX hockeyPlayer_full_name ON hockeyPlayer(full_name);
+
+INSERT INTO hockeyPlayer (player_number, full_name)
+VALUES (15, 'Ryan Getzlaf');
+
+selectAll:
+SELECT *
+FROM hockeyPlayer;
+
+insert:
+INSERT INTO hockeyPlayer(player_number, full_name)
+VALUES (?, ?);
+
+insertFullPlayerObject:
+INSERT INTO hockeyPlayer(player_number, full_name)
+VALUES ?;
\ No newline at end of file
diff --git a/src/main/sqldelight/dev/hossain/githubstats/ResponseCache.sq b/src/main/sqldelight/dev/hossain/githubstats/ResponseCache.sq
new file mode 100644
index 00000000..290fa158
--- /dev/null
+++ b/src/main/sqldelight/dev/hossain/githubstats/ResponseCache.sq
@@ -0,0 +1,30 @@
+CREATE TABLE IF NOT EXISTS response_cache
+(
+ request_url character varying(512) NOT NULL,
+ id integer NOT NULL,
+ response json NOT NULL,
+ CONSTRAINT response_cache_pkey PRIMARY KEY (id)
+);
+
+
+selectAll:
+SELECT *
+FROM response_cache;
+
+insert:
+INSERT INTO response_cache(id, request_url, response)
+VALUES ( ?, ?, ?);
+
+select:
+SELECT * FROM response_cache
+WHERE request_url = ?;
+
+delete:
+DELETE FROM response_cache
+WHERE request_url = ?;
+
+deleteAll:
+DELETE FROM response_cache;
+
+count:
+SELECT COUNT(*) FROM response_cache;
\ No newline at end of file