diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..334ff14 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +cvApi \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index bebf356..f6a6dc4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,10 +1,12 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { + id("com.squareup.sqldelight") kotlin("jvm") version "1.7.10" } -group = "fr.louveau-amine" +group = "fr.louveauAmine" version = "1.0-SNAPSHOT" repositories { @@ -15,6 +17,7 @@ dependencies { testImplementation(kotlin("test")) implementation("io.javalin:javalin:4.6.4") implementation("org.slf4j:slf4j-simple:2.0.1") + implementation("com.squareup.sqldelight:sqlite-driver:1.5.3") } tasks.test { @@ -23,4 +26,11 @@ tasks.test { tasks.withType { kotlinOptions.jvmTarget = "1.8" +} + +sqldelight { + database("CVApiDB") { + packageName = "fr.louveauAmine.cvApi.dao" + sourceFolders = listOf("sqldelight") + } } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index c2d4629..645c50b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,20 @@ +pluginManagement { + repositories { + mavenLocal() + mavenCentral() + jcenter() + google() + gradlePluginPortal() + } -rootProject.name = "cv-api" + resolutionStrategy { + eachPlugin { + if (requested.id.id == "com.squareup.sqldelight") { + useModule("com.squareup.sqldelight:gradle-plugin:1.5.3") + } + } + } +} + +rootProject.name = "cvApi" diff --git a/src/main/kotlin/controller/EducationYearController.kt b/src/main/kotlin/controller/EducationYearController.kt new file mode 100644 index 0000000..e1a17cf --- /dev/null +++ b/src/main/kotlin/controller/EducationYearController.kt @@ -0,0 +1,27 @@ +package controller + +import io.javalin.apibuilder.CrudHandler +import io.javalin.http.Context + +class EducationYearController : CrudHandler { + override fun create(ctx: Context) { + TODO("Not yet implemented") + } + + override fun delete(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun getAll(ctx: Context) { + TODO("Not yet implemented") + } + + override fun getOne(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun update(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + +} diff --git a/src/main/kotlin/controller/InterestController.kt b/src/main/kotlin/controller/InterestController.kt new file mode 100644 index 0000000..d37aa8f --- /dev/null +++ b/src/main/kotlin/controller/InterestController.kt @@ -0,0 +1,27 @@ +package controller + +import io.javalin.apibuilder.CrudHandler +import io.javalin.http.Context + +class InterestController : CrudHandler { + override fun create(ctx: Context) { + TODO("Not yet implemented") + } + + override fun delete(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun getAll(ctx: Context) { + TODO("Not yet implemented") + } + + override fun getOne(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun update(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + +} diff --git a/src/main/kotlin/controller/JobController.kt b/src/main/kotlin/controller/JobController.kt new file mode 100644 index 0000000..3551571 --- /dev/null +++ b/src/main/kotlin/controller/JobController.kt @@ -0,0 +1,27 @@ +package controller + +import io.javalin.apibuilder.CrudHandler +import io.javalin.http.Context + +class JobController : CrudHandler { + override fun create(ctx: Context) { + TODO("Not yet implemented") + } + + override fun delete(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun getAll(ctx: Context) { + TODO("Not yet implemented") + } + + override fun getOne(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun update(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + +} diff --git a/src/main/kotlin/controller/LanguageController.kt b/src/main/kotlin/controller/LanguageController.kt new file mode 100644 index 0000000..7dada31 --- /dev/null +++ b/src/main/kotlin/controller/LanguageController.kt @@ -0,0 +1,27 @@ +package controller + +import io.javalin.apibuilder.CrudHandler +import io.javalin.http.Context + +class LanguageController : CrudHandler { + override fun create(ctx: Context) { + TODO("Not yet implemented") + } + + override fun delete(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun getAll(ctx: Context) { + TODO("Not yet implemented") + } + + override fun getOne(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun update(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + +} diff --git a/src/main/kotlin/controller/MeController.kt b/src/main/kotlin/controller/MeController.kt new file mode 100644 index 0000000..8a6a615 --- /dev/null +++ b/src/main/kotlin/controller/MeController.kt @@ -0,0 +1,7 @@ +package controller + +class MeController { + fun getMe() { + TODO("Not yet implemented") + } +} \ No newline at end of file diff --git a/src/main/kotlin/controller/ProfileController.kt b/src/main/kotlin/controller/ProfileController.kt new file mode 100644 index 0000000..575667c --- /dev/null +++ b/src/main/kotlin/controller/ProfileController.kt @@ -0,0 +1,27 @@ +package controller + +import io.javalin.apibuilder.CrudHandler +import io.javalin.http.Context + +class ProfileController : CrudHandler { + override fun create(ctx: Context) { + TODO("Not yet implemented") + } + + override fun delete(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun getAll(ctx: Context) { + TODO("Not yet implemented") + } + + override fun getOne(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun update(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + +} diff --git a/src/main/kotlin/controller/SideProjectController.kt b/src/main/kotlin/controller/SideProjectController.kt new file mode 100644 index 0000000..c86ecdf --- /dev/null +++ b/src/main/kotlin/controller/SideProjectController.kt @@ -0,0 +1,27 @@ +package controller + +import io.javalin.apibuilder.CrudHandler +import io.javalin.http.Context + +class SideProjectController : CrudHandler { + override fun create(ctx: Context) { + TODO("Not yet implemented") + } + + override fun delete(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun getAll(ctx: Context) { + TODO("Not yet implemented") + } + + override fun getOne(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun update(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + +} diff --git a/src/main/kotlin/controller/TagController.kt b/src/main/kotlin/controller/TagController.kt new file mode 100644 index 0000000..1fe8e3b --- /dev/null +++ b/src/main/kotlin/controller/TagController.kt @@ -0,0 +1,27 @@ +package controller + +import io.javalin.apibuilder.CrudHandler +import io.javalin.http.Context + +class TagController : CrudHandler { + override fun create(ctx: Context) { + TODO("Not yet implemented") + } + + override fun delete(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun getAll(ctx: Context) { + TODO("Not yet implemented") + } + + override fun getOne(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + + override fun update(ctx: Context, resourceId: String) { + TODO("Not yet implemented") + } + +} diff --git a/src/main/kotlin/server.kt b/src/main/kotlin/server.kt index 4dc3a38..e041faf 100644 --- a/src/main/kotlin/server.kt +++ b/src/main/kotlin/server.kt @@ -1,6 +1,50 @@ +import com.squareup.sqldelight.db.SqlDriver +import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver +import controller.* +import fr.louveauAmine.cvApi.dao.CVApiDB +import fr.louveauAmine.cvApi.dao.PROFILE import io.javalin.Javalin +import io.javalin.apibuilder.ApiBuilder +import io.javalin.core.security.RouteRole + +enum class ApiRole : RouteRole { PUBLIC, BASIC_AUTHED } fun main() { - val app = Javalin.create().start(7070) - app.get("/") { ctx -> ctx.result("Hello World") } + val driver: SqlDriver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY) + CVApiDB.Schema.create(driver) + val database = CVApiDB(driver) + + database.profileQueries.insertProfile(PROFILE("Amine Louveau", "truc", "tata", "prout", null, null, null, null)) + + val app = Javalin.create{ + it.accessManager { handler, ctx, permittedRoles -> + val auth = ctx.header("Authorization").orEmpty() + val isBasicAuthed = auth == System.getenv("LDC_AUTH") + when { + permittedRoles.contains(ApiRole.PUBLIC) -> handler.handle(ctx) + permittedRoles.contains(ApiRole.BASIC_AUTHED) && isBasicAuthed -> handler.handle(ctx) + else -> ctx.status(401).json("Unauthorized") + } + } + }.start(7070) + + + + + + app.routes { + ApiBuilder.path("api") { + ApiBuilder.get("me", { + MeController().getMe() + }, ApiRole.BASIC_AUTHED) + + ApiBuilder.crud("education/{education-id}", EducationYearController(), ApiRole.BASIC_AUTHED) + ApiBuilder.crud("interest/{interest-id}", InterestController(), ApiRole.BASIC_AUTHED) + ApiBuilder.crud("job/{job-id}", JobController(), ApiRole.BASIC_AUTHED) + ApiBuilder.crud("language/{lang-id}", LanguageController(), ApiRole.BASIC_AUTHED) + ApiBuilder.crud("profile/{profile-id}", ProfileController(), ApiRole.BASIC_AUTHED) + ApiBuilder.crud("side-project/{side-id}", SideProjectController(), ApiRole.BASIC_AUTHED) + ApiBuilder.crud("tag/{tag-id}", TagController(), ApiRole.BASIC_AUTHED) + } + } } \ No newline at end of file diff --git a/src/main/sqldelight/fr/louveauAmine/cvApi/dao/EducationYear.sq b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/EducationYear.sq new file mode 100644 index 0000000..3be66e6 --- /dev/null +++ b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/EducationYear.sq @@ -0,0 +1,17 @@ +CREATE TABLE EDUCATIONYEAR ( + `endDate` TEXT NOT NULL, + `school` TEXT NOT NULL, + `name` TEXT NOT NULL, + PRIMARY KEY(`endDate`, `school`) +); + +CREATE INDEX educationyear_date_school ON EDUCATIONYEAR(`endDate`, `school`); + +educationYears: +SELECT * FROM EDUCATIONYEAR; + +insertEducationYear: +INSERT OR REPLACE INTO EDUCATIONYEAR VALUES ?; + +deleteEducationYear: +DELETE FROM EDUCATIONYEAR WHERE `endDate` = ? AND `school` = ?; \ No newline at end of file diff --git a/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Interests.sq b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Interests.sq new file mode 100644 index 0000000..4c9d3f0 --- /dev/null +++ b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Interests.sq @@ -0,0 +1,16 @@ +CREATE TABLE INTEREST ( + `theme` TEXT NOT NULL, + `description` TEXT NOT NULL, + PRIMARY KEY (`theme`) +); + +CREATE INDEX interest_key ON INTEREST(`theme`); + +interests: +SELECT * FROM INTEREST; + +insertInterest: +INSERT OR REPLACE INTO INTEREST VALUES ?; + +deleteInterest: +DELETE FROM INTEREST WHERE `theme` = ?; \ No newline at end of file diff --git a/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Jobs.sq b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Jobs.sq new file mode 100644 index 0000000..aa15496 --- /dev/null +++ b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Jobs.sq @@ -0,0 +1,19 @@ +CREATE TABLE JOB ( + `jobTitle` TEXT NOT NULL, + `start` TEXT NOT NULL, + `end` TEXT NOT NULL, + `company` TEXT NOT NULL, + `tasks` TEXT NOT NULL, + PRIMARY KEY (`start`, `end`, `company`) +); + +CREATE INDEX job_index ON JOB(`start`, `end`, `company`); + +jobs: +SELECT * FROM JOB; + +insertJob: +INSERT OR REPLACE INTO JOB VALUES ?; + +deleteJob: +DELETE FROM JOB WHERE `start` = ? AND `end` = ? AND `company` = ?; \ No newline at end of file diff --git a/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Languages.sq b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Languages.sq new file mode 100644 index 0000000..8928e3b --- /dev/null +++ b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Languages.sq @@ -0,0 +1,16 @@ +CREATE TABLE LANGUAGE ( + `lang` TEXT NOT NULL, + `level` TEXT NOT NULL, + PRIMARY KEY(`lang`) +); + +CREATE INDEX lang_lang ON LANGUAGE(`lang`); + +langs: +SELECT * FROM LANGUAGE; + +insertLang: +INSERT OR REPLACE INTO LANGUAGE VALUES ?; + +deleteLang: +DELETE FROM LANGUAGE WHERE `lang` = ?; \ No newline at end of file diff --git a/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Migrations.sq b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Migrations.sq new file mode 100644 index 0000000..1425e0d --- /dev/null +++ b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Migrations.sq @@ -0,0 +1,16 @@ +CREATE TABLE MIGRATION ( + `identifier` TEXT NOT NULL, + `done` INTEGER AS Boolean DEFAULT 0 NOT NULL, + PRIMARY KEY (`identifier`) +); + +CREATE INDEX migration_index ON MIGRATION(`identifier`); + +migrations: +SELECT * FROM MIGRATION; + +insertMigration: +INSERT OR REPLACE INTO MIGRATION VALUES ?; + +deleteMigration: +DELETE FROM MIGRATION WHERE `identifier` = ?; \ No newline at end of file diff --git a/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Profile.sq b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Profile.sq new file mode 100644 index 0000000..6c66816 --- /dev/null +++ b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Profile.sq @@ -0,0 +1,22 @@ +CREATE TABLE PROFILE ( + `name` TEXT NOT NULL, + `title` TEXT NOT NULL, + `quote` TEXT NOT NULL, + `picture` TEXT NOT NULL, + `email` TEXT, + `phone` TEXT, + `linkedin` TEXT, + `source` TEXT, + PRIMARY KEY (`name`) +); + +CREATE INDEX profile_name ON PROFILE(`name`); + +profiles: +SELECT * FROM PROFILE; + +insertProfile: +INSERT OR REPLACE INTO PROFILE VALUES ?; + +deleteProfile: +DELETE FROM PROFILE WHERE `name` = ?; \ No newline at end of file diff --git a/src/main/sqldelight/fr/louveauAmine/cvApi/dao/SideProjects.sq b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/SideProjects.sq new file mode 100644 index 0000000..1dff7b6 --- /dev/null +++ b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/SideProjects.sq @@ -0,0 +1,23 @@ +CREATE TABLE SIDEPROJECT ( + `description` TEXT NOT NULL, + `title` TEXT, + `url` TEXT, + `category` TEXT NOT NULL , + PRIMARY KEY (`description`, `title`, `url`, `category`) +); + +CREATE INDEX sideproject_index ON SIDEPROJECT(`description`, `title`, `url`, `category`); + +sideProjects: +SELECT * FROM SIDEPROJECT; + +sideProjectsByCategory: +SELECT * FROM SIDEPROJECT +GROUP BY `category` +ORDER BY COUNT(`category`) DESC; + +insertSideProject: +INSERT OR REPLACE INTO SIDEPROJECT VALUES ?; + +deleteSideProject: +DELETE FROM SIDEPROJECT WHERE `description` = ? AND `category` = ?; \ No newline at end of file diff --git a/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Tags.sq b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Tags.sq new file mode 100644 index 0000000..ab69b81 --- /dev/null +++ b/src/main/sqldelight/fr/louveauAmine/cvApi/dao/Tags.sq @@ -0,0 +1,17 @@ +CREATE TABLE TAG ( + `name` TEXT NOT NULL, + `workThing` INTEGER AS Boolean DEFAULT 1 NOT NULL, + `category` TEXT NOT NULL, + PRIMARY KEY (`name`) +); + +CREATE INDEX tag_name ON TAG(`name`); + +tags: +SELECT * FROM TAG; + +insertTag: +INSERT OR REPLACE INTO TAG VALUES ?; + +deleteTag: +DELETE FROM TAG WHERE `name` = ? AND `category` = ?; \ No newline at end of file