package Ġcom . st as bar . app . database Ċ Ċ import Ġcom . st as bar . app . database . models .* Ċ import Ġcom . st as bar . app . models . Book Ċ import Ġcom . st as bar . app . models . Quote Ċ import Ġcom . st as bar . app . models . She lf Ċ import Ġkotlinx . coroutines . Executor Coroutine Dispatcher Ċ import Ġkotlinx . coroutines . as Coroutine Dispatcher Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġmu . Kotlin Logging Ċ import Ġorg . jetbrains . ex posed . sql .* Ċ import Ġorg . jetbrains . ex posed . sql . transactions . transaction Ċ import Ġjava . util . concurrent . Executors Ċ Ċ abstract Ġclass ĠDatabase Impl ( ĊĠ Ġpool Size : ĠInt , ĊĠ Ġdriver : ĠString , ĊĠ Ġjdbc Connection Url : ĠString , ĊĠ Ġusername : ĠString , ĊĠ Ġpassword : ĠString Ċ ) Ġ: ĠBooks Database Ġ{ ĊĠ Ġprivate Ġval Ġlogger Ġ= ĠKotlin Logging . logger Ġ{ Ġ} ĊĠ Ġprivate Ġval Ġdispatcher : ĠExecutor Coroutine Dispatcher Ġ= ĠExec utors . new Fixed ThreadPool ( pool Size ). as Coroutine Dispatcher () ĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġlogger . info (" Using ĠJDBC ĠUrl : Ġ$ jdbc Connection Url Ġusername Ġ$ username ") ĊĠĠĠ ĠDatabase . connect ( ĊĠĠĠĠĠ Ġjdbc Connection Url , ĊĠĠĠĠĠ Ġdriver , ĊĠĠĠĠĠ Ġusername , ĊĠĠĠĠĠ Ġpassword ĊĠĠĠ Ġ) ĊĠĠĠ Ġtransaction Ġ{ ĊĠĠĠĠĠ ĠSchema Utils . create ( Books , ĠQu otes , ĠS hel ves , ĠBook S hel ves ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġsuspend Ġfun ĠgetAll Books (): ĠList < Book > Ġ= Ġwith Context ( dispatcher ) Ġ{ ĊĠĠĠ Ġtransaction Ġ{ ĊĠĠĠĠĠ Ġ( Books ). selectAll () ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġit . to Book ( run Blocking Ġ{ Ġget Book S hel ves ( it [ Books . hash ]) Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġsuspend Ġfun Ġinsert OrUpdate Books ( books : ĠList < Book >) Ġ{ ĊĠĠĠ Ġwith Context ( dispatcher ) Ġ{ ĊĠĠĠĠĠ Ġtransaction Ġ{ ĊĠĠĠĠĠĠĠ Ġbooks . forEach Ġ{ Ġbook Ġ-> ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( book . s hel ves . isEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Book Ġmust Ġbelong Ġto Ġat Ġleast Ġone Ġshe lf ") ĊĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( Books . select Ġ{ ĠBooks . hash Ġeq Ġbook . hash Ġ}. first OrNull () Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinsert Book ( book ) ĊĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Book ( book ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĊĠ Ġprivate Ġfun Ġinsert Book ( book : ĠBook ) Ġ{ ĊĠĠĠ Ġlogger . debug (" about Ġto Ġinsert Ġ$ book ") ĊĠĠĠ ĠBooks . insert Ġ{ ĊĠĠĠĠĠ Ġit [ Books . hash ] Ġ= Ġbook . hash ĊĠĠĠĠĠ Ġit [ Books . title ] Ġ= Ġbook . title ĊĠĠĠĠĠ Ġit [ Books . rating ] Ġ= Ġbook . rating ĊĠĠĠĠĠ Ġit [ Books . good reads Id ] Ġ= Ġbook . good reads Id ĊĠĠĠĠĠ Ġit [ Books . author ] Ġ= Ġbook . author ĊĠĠĠĠĠ Ġit [ Books . isbn 1 0 ] Ġ= Ġbook . isbn 1 0 ĊĠĠĠĠĠ Ġit [ Books . isbn 1 3 ] Ġ= Ġbook . isbn 1 3 ĊĠĠĠĠĠ Ġit [ Books . imageUrl ] Ġ= Ġbook . imageUrl ĊĠĠĠĠĠ Ġit [ Books . small ImageUrl ] Ġ= Ġbook . small ImageUrl ĊĠĠĠ Ġ} ĊĠĠĠ Ġbook . s hel ves . forEach Ġ{ Ġshe lf Ġ-> ĊĠĠĠĠĠ Ġval Ġshe lf Id Ġ= ĠS hel ves . insert Ġ{ ĊĠĠĠĠĠĠĠ Ġit [ S hel ves . value ] Ġ= Ġshe lf . value ĊĠĠĠĠĠ Ġ} Ġget ĠS hel ves . id ĊĊĠĠĠĠĠ ĠBook S hel ves . insert Ġ{ ĊĠĠĠĠĠĠĠ Ġit [ Book S hel ves . shelf ] Ġ= Ġshe lf Id !! ĊĠĠĠĠĠĠĠ Ġit [ Book S hel ves . book ] Ġ= Ġbook . hash ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġupdate Book ( book : ĠBook ) Ġ{ ĊĠĠĠ Ġlogger . debug (" about Ġto Ġupdate Ġ$ book ") ĊĠĠĠ ĠBooks . update ({ ĠBooks . hash Ġeq Ġbook . hash Ġ}) Ġ{ ĊĠĠĠĠĠ Ġit [ Books . title ] Ġ= Ġbook . title ĊĠĠĠĠĠ Ġit [ Books . rating ] Ġ= Ġbook . rating ĊĠĠĠĠĠ Ġit [ Books . good reads Id ] Ġ= Ġbook . good reads Id ĊĠĠĠĠĠ Ġit [ Books . author ] Ġ= Ġbook . author ĊĠĠĠĠĠ Ġit [ Books . isbn 1 0 ] Ġ= Ġbook . isbn 1 0 ĊĠĠĠĠĠ Ġit [ Books . isbn 1 3 ] Ġ= Ġbook . isbn 1 3 ĊĠĠĠĠĠ Ġit [ Books . imageUrl ] Ġ= Ġbook . imageUrl ĊĠĠĠĠĠ Ġit [ Books . small ImageUrl ] Ġ= Ġbook . small ImageUrl ĊĠĠĠ Ġ} ĊĊĠĠĠ ĠBook S hel ves . delete Where Ġ{ ĠBook S hel ves . book Ġeq Ġbook . hash Ġ} ĊĊĠĠĠ Ġbook . s hel ves . forEach Ġ{ Ġshe lf Ġ-> ĊĠĠĠĠĠ Ġval Ġshe lf Id Ġ= ĠS hel ves . insert Ġ{ ĊĠĠĠĠĠĠĠ Ġit [ S hel ves . value ] Ġ= Ġshe lf . value ĊĠĠĠĠĠ Ġ} Ġget ĠS hel ves . id ĊĊĠĠĠĠĠ ĠBook S hel ves . insert Ġ{ ĊĠĠĠĠĠĠĠ Ġit [ Book S hel ves . shelf ] Ġ= Ġshe lf Id !! ĊĠĠĠĠĠĠĠ Ġit [ Book S hel ves . book ] Ġ= Ġbook . hash ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġsuspend Ġfun Ġget Books From She lf ( shelf : ĠString ): ĠList < Book > Ġ= Ġwith Context ( dispatcher ) Ġ{ ĊĠĠĠ Ġtransaction Ġ{ ĊĠĠĠĠĠ Ġ( Book S hel ves Ġinner Join ĠS hel ves Ġinner Join ĠBooks ). select Ġ{ ĠS hel ves . value Ġeq Ġshe lf Ġ} ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . to Book ( run Blocking Ġ{ Ġget Book S hel ves ( it [ Books . hash ]) Ġ}) Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġsuspend Ġfun Ġget Book S hel ves ( book Hash : ĠString ): ĠList < She lf > Ġ= Ġwith Context ( dispatcher ) Ġ{ ĊĠĠĠ Ġtransaction Ġ{ ĊĠĠĠĠĠ Ġ( Book S hel ves Ġinner Join ĠS hel ves Ġinner Join ĠBooks ). select Ġ{ ĠBooks . hash Ġeq Ġbook Hash Ġ} ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . to She lf () Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠQu otes ĊĠĠ Ġ*/ ĊĊĠ Ġoverride Ġsuspend Ġfun ĠgetAll Quotes ( limit : ĠInt ): ĠList < Quote > Ġ= Ġwith Context ( dispatcher ) Ġ{ ĊĠĠĠ Ġtransaction Ġ{ ĊĠĠĠĠĠ Ġ( Quotes Ġleft Join ĠBooks ). selectAll () ĊĠĠĠĠĠĠĠ Ġ. orderBy ( Quotes . position Ġto Ġtrue ) ĊĠĠĠĠĠĠĠ Ġ. also Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( limit Ġ!= Ġ- 1 ) Ġit . limit ( limit ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. also Ġ{ Ġprintln (" selected Ġ${ it . count ()} Ġquotes ") Ġ} ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġit . to Quote ( run Blocking Ġ{ Ġget Book S hel ves ( it [ Books . hash ]) Ġ}) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġoverride Ġsuspend Ġfun Ġinsert OrUpdate Quotes ( quotes : ĠList < Quote >) Ġ{ ĊĠĠĠ Ġwith Context ( dispatcher ) Ġ{ ĊĠĠĠĠĠ Ġtransaction Ġ{ ĊĠĠĠĠĠĠĠ Ġquotes . forEach Ġ{ Ġquote Ġ-> ĊĠĠĠĠĠĠĠĠĠ Ġval Ġbook Ġ= Ġquote . book ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBooks ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. select Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( Books . hash Ġeq Ġit . hash ) Ġor Ġ( Books . title Ġlike Ġit . title ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . to Book ( run Blocking Ġ{ Ġget Book S hel ves ( it . hash ) Ġ}) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( Quotes . select Ġ{ ĠQu otes . hash Ġeq Ġquote . hash Ġ}. first OrNull () Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinsert Quote ( quote , Ġbook ) ĊĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Quote ( quote , Ġbook ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġupdate Quote ( quote : ĠQuote , Ġbook : ĠBook ?) Ġ{ ĊĠĠĠ Ġlogger . debug (" about Ġto Ġupdate Ġquote Ġ$ quote ") ĊĠĠĠ Ġlogger . debug (" with Ġbook Ġ$ book ") ĊĊĠĠĠ ĠQu otes . update ({ ĠQu otes . hash Ġeq Ġquote . hash Ġ}) Ġ{ ĊĠĠĠĠĠ Ġit [ text ] Ġ= Ġquote . text ĊĠĠĠĠĠ Ġit [ author ] Ġ= Ġquote . author ĊĠĠĠĠĠ Ġit [ position ] Ġ= Ġquote . position ĊĠĠĠĠĠ Ġit [ book Hash ] Ġ= Ġbook ?. hash ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġinsert Quote ( quote : ĠQuote , Ġbook : ĠBook ?) Ġ{ ĊĠĠĠ Ġlogger . debug (" about Ġto Ġinsert Ġquote Ġ$ quote ") ĊĠĠĠ Ġlogger . debug (" with Ġbook Ġ$ book ") ĊĠĠĠ ĠQu otes . insert Ġ{ ĊĠĠĠĠĠ Ġit [ hash ] Ġ= Ġquote . hash ĊĠĠĠĠĠ Ġit [ text ] Ġ= Ġquote . text ĊĠĠĠĠĠ Ġit [ author ] Ġ= Ġquote . author ĊĠĠĠĠĠ Ġit [ position ] Ġ= Ġquote . position ĊĠĠĠĠĠ Ġit [ book Hash ] Ġ= Ġbook ?. hash ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ Ċ } Ċ