# Introduction
The School of Haskell published a [4-part tutorial series](https://www.fpcomplete.com/school/ide-tutorials/building-a-file-hosting-service-in-yesod) showing how to write a simple self-hosted file server application. Consider this article the 5th entry in that series. People have been asking how the example might be extended in various ways. The most common request is for uploaded files to be kept in a database so that they will be available after restarting the application.
The most straightforward approach will be to use the [persistent](http://hackage.haskell.org/package/persistent) family of libraries, and interface with an [SQLite](http://www.sqlite.org/) database. Persistent is the natural choice for a data access layer. It presents the database as a simple [ORM](http://en.wikipedia.org/wiki/Object-relational_mapping) (Object-relational mapping). This will allow us to use regular Haskell objects and a simple SQL-like query language to keep track of uploaded files.
SQLite was chosen because it is the easiest to start using. Persistent supports other database backends as well. We'll make switching to another one as easy as possible by constraining SQLite-specific code to a single module.
## Following Along
[Part 1](https://www.fpcomplete.com/school/advanced-haskell/building-a-file-hosting-service-in-yesod/part%201) of this series contains a section explaining many of the conventions used when presenting examples. We will adopt the same style here.
There are a number of ways to follow along. One option is to work off of your own copy of this project, implementing changes as we go. To do this I suggest cloning the [File Server template](https://www.fpcomplete.com/page/project-build) from within FP Haskell Center. All of the active code samples are ready to run. Simply click on the "Open in IDE" link, select "Main.hs" from the drop down list towards the top of your screen, and click on the play button.
For those who prefer to work from their local computer, there is a companion [GitHub project](https://github.com/mikesteele81/soh-file-server-tutorial-project) which can be cloned. Most sections will contain a link pointing to what the project should look like after changes have been made. The final active code sample will contain full commenting for readers to use as a basis for further work.
## Reviewing Current Design
[github branch: 05-00](https://github.com/mikesteele81/soh-file-server-tutorial-project/tree/05-00)
Let's start by reviewing how file storage is currently handled. The server always starts with an empty data set. An in-memory data structure is populated as users upload files. We use an |]
| otherwise = do
eText <- try . evaluate $ LT.decodeUtf8 bytes :: IO (Either SomeException LT.Text)
return $ case eText of
Left _ -> errorMessage
Right text -> [whamlet|
#{text}|] where errorMessage = [whamlet|Unable to display file contents.|] {-# START_FILE templates/default-layout.cassius #-} body font-family: Tahoma, Geneva, sans-serif font-size: 1pc form clear: both margin:auto position:relative text-decoration: none -webkit-border-radius: 5pt -moz-border-radius: 5pt border-radius: 5pt padding:1em border: 1pt solid #999 border: inset 1pt solid #333 /* Force form elements to be consistent with each other */ input, textarea, select, button margin: 1pt -webkit-box-sizing: border-box -moz-box-sizing: border-box box-sizing: border-box select width: 100% input display:block border: 1pt solid #999 input[type=submit] float: right background: #09C color: #fff -webkit-border-radius: 5pt -moz-border-radius: 5pt border-radius: 5pt border: 1pt solid #999 /* Change color on mouseover */ input[type=submit]:hover background:#fff color:#09c /* force bottom border to extend below floating elements */ form::after content: "" display: block visibility: hidden clear: both /* add rounded grey box around text */ pre -webkit-border-radius: 5pt -moz-border-radius: 5pt border-radius: 5pt border: 1pt solid #999 background: #DDD margin: 1em padding: 1em white-space: pre-wrap {-# START_FILE templates/default-layout.hamlet #-} ^{widget} {-# START_FILE templates/default-layout-wrapper.hamlet #-} $newline never $doctype 5#{pageTitle pc} ^{pageHead pc} ^{pageBody pc} {-# START_FILE templates/home.hamlet #-}Previously submitted files $if null storedFiles
No files have been uploaded yet. $else