package Ġcom . p amel aa h ill Ċ Ċ import Ġcom . zaxxer . hikari . HikariConfig Ċ import Ġcom . zaxxer . hikari . Hikari DataSource Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġorg . jetbrains . ex posed . sql .* Ċ import Ġorg . jetbrains . ex posed . sql . Schema Utils . create Ċ import Ġorg . jetbrains . ex posed . sql . transactions . transaction Ċ import Ġjava . io . ByteArray InputStream Ċ import Ġjava . io . File Ċ import Ġjava . net . URL Ċ import Ġjava . util .* Ċ import Ġjava . util . Date Ċ Ċ private Ġconst Ġval ĠIMAGE _ DIR Ġ= Ġ" images " Ċ Ċ class ĠIn sp iration Db Impl Ġ: ĠIn sp iration Db Ġ{ ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ ĠDatabase . connect ( hikari ()) ĊĠĠĠĠĠĠĠ Ġtransaction Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate ( In sp ir ations ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate ( Tags ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate ( In sp iration Tags ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġcreate In sp iration ( ĊĠĠĠĠĠĠĠ ĠuserId : ĠLong , ĊĠĠĠĠĠĠĠ Ġfile Extension : ĠString , ĊĠĠĠĠĠĠĠ ĠinputStream : ĠByteArrayInputStream ĊĠĠĠ Ġ): ĠIn sp iration ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdb Query Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Save Ġthe Ġfile ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinsp iration Image Ġ= ĠFile ("$ IMAGE _ DIR /${ UUID . randomUUID ()}. $ file Extension ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinsp iration Image . write Bytes ( inputStream . read Bytes ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Insert Ġthe Ġinsp iration ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġid Ġ= ĠIn sp ir ations . insert Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit [ In sp ir ations . userId ] Ġ= ĠuserId ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit [ In sp ir ations . file Url ] Ġ= Ġinsp iration Image . to URI (). to URL (). to External Form () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit [ In sp ir ations . generated Date ] Ġ= ĠDate (). time ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġget ĠIn sp ir ations . id ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġid ?. let Ġ{ Ġsync Find In sp iration ById ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġupdate In sp iration ( id : ĠLong , Ġtag Titles : ĠList < String >): ĠIn sp iration ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdb Query Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ensure Ġall Ġthe Ġtags Ġare Ġin Ġthe Ġtable ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtag Titles . map Ġ{ Ġtag Title Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontains Tag Ġ= Ġ! Tags . select Ġ{ ĠTags . title Ġeq Ġtag Title Ġ}. empty () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! contains Tag ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTags . insert Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit [ Tags . title ] Ġ= Ġtag Title ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Get Ġthe Ġtags ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtags : ĠList < Tag > Ġ= Ġtag Titles . flatMap Ġ{ Ġtag Title Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTags . select Ġ{ ĠTags . title Ġeq Ġtag Title Ġ}. map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmap Tags To Tag ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Replace Ġall Ġthe Ġtags ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIn sp iration Tags . delete Where Ġ{ ĠIn sp iration Tags . insp iration Id Ġeq Ġid Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtags . forEach Ġ{ Ġtag Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIn sp iration Tags . insert Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit [ In sp iration Tags . insp iration Id ] Ġ= Ġid ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit [ In sp iration Tags . tag Id ] Ġ= Ġtag . id ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsync Find In sp iration ById ( id ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġfind In sp ir ations By UserId ( userId : ĠLong ): ĠList < In sp iration > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdb Query Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIn sp ir ations . select Ġ{ ĠIn sp ir ations . userId Ġeq ĠuserId Ġ}. map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmap In sp ir ations To In sp iration ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġfind In sp iration Image ById ( id : ĠLong ): ĠFile ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġfind In sp iration ById ( id )?. file Url ?. to URI ()?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFile ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġfind In sp iration ById ( id : ĠLong ): ĠIn sp iration ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdb Query Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsync Find In sp iration ById ( id ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġfind In sp ir ations By Tag ( tag Id : ĠLong ): ĠList < In sp iration > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdb Query Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ( In sp ir ations Ġinner Join ĠIn sp iration Tags ). select Ġ{ ĠIn sp iration Tags . tag Id Ġeq Ġtag Id Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map NotNull Ġ{ Ġmap In sp ir ations To In sp iration ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġfind Tags By Title ( title : ĠString ): ĠList < Tag > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdb Query Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTags . select Ġ{ ĠTags . title Ġlike Ġtitle Ġ}. map NotNull Ġ{ Ġmap Tags To Tag ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġfind Tags (): ĠList < Tag > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdb Query Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTags . selectAll (). map NotNull Ġ{ Ġmap Tags To Tag ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġadd Tags To In sp iration ( id : ĠLong ): ĠList < Tag > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ( In sp iration Tags Ġinner Join ĠTags ). select Ġ{ ĠIn sp iration Tags . insp iration Id Ġeq Ġid Ġ}. map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmap Tags To Tag ( it ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsync Find In sp iration ById ( id : ĠLong ): ĠIn sp iration ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠIn sp ir ations . select Ġ{ ĠIn sp ir ations . id Ġeq Ġid Ġ}. map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmap In sp ir ations To In sp iration ( it ) ĊĠĠĠĠĠĠĠ Ġ}. first OrNull () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmap In sp ir ations To In sp iration ( result Row : ĠResult Row ) Ġ= ĠIn sp iration ( ĊĠĠĠĠĠĠĠ Ġid Ġ= Ġresult Row [ In sp ir ations . id ], ĊĠĠĠĠĠĠĠ ĠuserId Ġ= Ġresult Row [ In sp ir ations . userId ], ĊĠĠĠĠĠĠĠ Ġfile Url Ġ= ĠURL ( result Row [ In sp ir ations . file Url ]), ĊĠĠĠĠĠĠĠ Ġtags Ġ= Ġadd Tags To In sp iration ( result Row [ In sp ir ations . id ]), ĊĠĠĠĠĠĠĠ Ġgenerated Date Ġ= Ġresult Row [ In sp ir ations . generated Date ] ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġfun Ġmap Tags To Tag ( result Row : ĠResult Row ) Ġ= ĠTag ( ĊĠĠĠĠĠĠĠ Ġid Ġ= Ġresult Row [ Tags . id ], ĊĠĠĠĠĠĠĠ Ġtitle Ġ= Ġresult Row [ Tags . title ] ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġ< T > Ġdb Query ( block : Ġ() Ġ-> ĠT ): ĠT Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwith Context ( Dispatch ers . IO ) ĊĠĠĠĠĠĠĠ Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtransaction Ġ{ Ġblock () Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġh ikari (): ĠH ikari DataSource Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġconfig Ġ= ĠH ikariConfig () ĊĠĠĠĠĠĠĠ Ġconfig . driver ClassName Ġ= Ġ" org . h 2 . Driver " ĊĠĠĠĠĠĠĠ Ġconfig . jdbc Url Ġ= Ġ" jdbc : h 2 : mem : test " ĊĠĠĠĠĠĠĠ Ġconfig . maximum PoolSize Ġ= Ġ 3 ĊĠĠĠĠĠĠĠ Ġconfig . is Auto Commit Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġconfig . transaction Isolation Ġ= Ġ" TRANSACTION _ REPEAT ABLE _ READ " ĊĠĠĠĠĠĠĠ Ġconfig . validate () ĊĠĠĠĠĠĠĠ Ġreturn ĠH ikari DataSource ( config ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġobject ĠIn sp ir ations Ġ: ĠTable () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġlong (" id "). primaryKey (). auto Increment () ĊĠĠĠĠĠĠĠ Ġval ĠuserId Ġ= Ġlong (" userId ") ĊĠĠĠĠĠĠĠ Ġval Ġfile Url Ġ= Ġvarchar (" file Url ", Ġ 1 0 2 4 ) ĊĠĠĠĠĠĠĠ Ġval Ġgenerated Date Ġ= Ġlong (" generated Date ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġobject ĠTags Ġ: ĠTable () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġlong (" id "). primaryKey (). auto Increment () ĊĠĠĠĠĠĠĠ Ġval Ġtitle Ġ= Ġvarchar (" title ", Ġ 1 0 2 4 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġobject ĠIn sp iration Tags Ġ: ĠTable () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġinsp iration Id Ġ= Ġlong (" insp iration Id ") Ġreferences ĠIn sp ir ations . id ĊĠĠĠĠĠĠĠ Ġval Ġtag Id Ġ= Ġlong (" tag Id ") Ġreferences ĠTags . id ĊĠĠĠ Ġ} Ċ }