p2-insta485-serverside
SQLite Tutorial
SQLite is a library that implements a small SQL database engine. An SQLite database is stored in a file on your hard drive.
If you’re new to SQL, take a look at the w3Schools SQL Intro.
Install
First, we’ll install the sqlite3
command line utility.
Linux and Windows Subsystem for Linux
$ sudo apt-get install sqlite3
MacOS
$ brew install sqlite3
All operating systems
Verify that you have the sqlite3
command line tool installed. Your version might be different.
$ sqlite3 --version
3.29.0 2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6
Manual database manipulation
Create a database with one table in it. The database lives in the file var/insta485.sqlite3
. The var
directory is commonly where the system writes data during the course of its operation.
$ mkdir var
$ sqlite3 var/insta485.sqlite3
sqlite> CREATE TABLE users(
username VARCHAR(20) NOT NULL,
fullname VARCHAR(40) NOT NULL,
PRIMARY KEY(username)
);
sqlite> .tables
users
sqlite> .exit
Now, we can add a user to the database. Your output formatting may be slightly different..
$ sqlite3 var/insta485.sqlite3
sqlite> INSERT INTO users(username, fullname)
VALUES ('awdeorio', 'Andrew DeOrio');
sqlite> SELECT * FROM users;
awdeorio|Andrew DeOrio
sqlite> .exit
You can also run an SQL statement in one line from the command line.
$ sqlite3 var/insta485.sqlite3 "SELECT * FROM users;"
awdeorio|Andrew DeOrio
Pro-tip: Enable table pretty-printing with an SQlite configuration file in your home directory. Create a file called ~/.sqliterc
and put this in it:
.mode column
.header on
Now print a table again and you’ll see column labels.
$ sqlite3 var/insta485.sqlite3 "SELECT * FROM users;"
-- Loading resources from /Users/awdeorio/.sqliterc
username fullname
---------- -------------
awdeorio Andrew DeOrio
Automated database manipulation
It’s easier to put SQL commands in a file and then read the file with sqlite3
. Create the files first:
$ touch sql/schema.sql
$ touch sql/data.sql
Put this in sql/schema.sql
:
PRAGMA foreign_keys = ON;
CREATE TABLE users(
username VARCHAR(20) NOT NULL,
fullname VARCHAR(40) NOT NULL,
PRIMARY KEY(username)
);
And put this in sql/data.sql
:
PRAGMA foreign_keys = ON;
INSERT INTO users(username, fullname)
VALUES ('awdeorio', 'Andrew DeOrio');
Now, we’ll start over and run both of these SQL scripts.
$ rm var/insta485.sqlite3
$ sqlite3 var/insta485.sqlite3 < sql/schema.sql
$ sqlite3 var/insta485.sqlite3 < sql/data.sql
Note: Foreign key support in SQLite 3 is disabled by default in SQlite 3 (docs). The line of SQL PRAGMA foreign_keys = ON
turns on foreign key support on a per-connection basis.
Database management shell script
Automate database management tasks with a shell script. Remember to use best shell scripting practices from the Shell Scripting Tutorial.
In this example, the script is called insta485db
and it lives in the bin/
directory. We show the output of the instructor solution, but we’ll grade your script only on its functionality, not the output.
Usage
Calling the script without arguments displays a usage message.
$ ./bin/insta485db
Usage: ./bin/insta485db (create|destroy|reset|dump)
Create
The create
argument runs the sqlite3
command line utility. You might also copy files used to initialize an uploads/
directory.
$ ./bin/insta485db create
+ mkdir -p var/uploads
+ sqlite3 var/insta485.sqlite3 < sql/schema.sql
+ sqlite3 var/insta485.sqlite3 < sql/data.sql
+ cp sql/uploads/* var/uploads/
Notice that sql/uploads
contains the original starter files, while var/uploads/
is a copy. The web server will upload new photos to var/uploads
later. This isn’t specific to SQLite, but it’s helpful for EECS 485 project 2 and project 3.
Avoid clobbering an existing database.
$ ./bin/insta485db create
Error: database already exists
Destroy
The destroy
argument removes the database. You might also want to remove user-created files like an uploads/
directory.
$ ./bin/insta485db destroy
+ rm -rf var/insta485.sqlite3 var/uploads
Reset
The reset
argument does the same thing as destroy
followed by create
.
$ ./bin/insta485db reset
+ rm -rf var/insta485.sqlite3 var/uploads
+ mkdir -p var/uploads
+ sqlite3 var/insta485.sqlite3 < sql/schema.sql
+ sqlite3 var/insta485.sqlite3 < sql/data.sql
+ cp sql/uploads/* var/uploads/
Dump
The dump
argument prints everything in the database. The exact format is up to you. Note to EECS 485 students: the autograder will only check for the right data in the output, not the format.
$ ./bin/insta485db dump
+ sqlite3 -batch -line var/insta485.sqlite3 'SELECT * FROM comments'
commentid = 1
owner = awdeorio
postid = 3
text = #chickensofinstagram
created = 2017-06-20 15:47:02
...
+ sqlite3 -batch -line var/insta485.sqlite3 'SELECT * FROM following'
username1 = awdeorio
username2 = jflinn
created = 2017-06-20 15:47:02
...
+ sqlite3 -batch -line var/insta485.sqlite3 'SELECT * FROM likes'
owner = awdeorio
postid = 1
created = 2017-06-20 15:47:02
...
+ sqlite3 -batch -line var/insta485.sqlite3 'SELECT * FROM posts'
postid = 1
filename = 122a7d27ca1d7420a1072f695d9290fad4501a41.jpg
owner = awdeorio
created = 2017-06-20 15:47:02
...
+ sqlite3 -batch -line var/insta485.sqlite3 'SELECT * FROM users'
username = awdeorio
fullname = Andrew DeOrio
email = awdeorio@umich.edu
filename = e1a7c5c32973862ee15173b0259e3efdb6a391af.jpg
password = sha512$a45ffdcc71884853a2cba9e6bc55e812$c739cef1aec45c6e345c8463136dc1ae2fe19963106cf748baf87c7102937aa96928aa1db7fe1d8da6bd343428ff3167f4500c8a61095fb771957b4367868fb8
created = 2017-06-20 15:47:02
Sample code
Here’s a starting point for the bin/insta485db
script.
#!/bin/bash
# insta485db
# Stop on errors
# See https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
set -Eeuo pipefail
# Sanity check command line options
usage() {
echo "Usage: $0 (create|destroy|reset|dump)"
}
if [ $# -ne 1 ]; then
usage
exit 1
fi
# Parse argument. $1 is the first argument
case $1 in
"create")
echo "FIXME implement me"
;;
"destroy")
echo "FIXME implement me"
;;
"reset")
echo "FIXME implement me"
;;
"dump")
echo "FIXME implement me"
;;
*)
usage
exit 1
;;
esac
Don’t forget to make the file executable with chmod +x bin/insta485db
.
Acknowledgments
Original document written by Andrew DeOrio awdeorio@umich.edu.
This document is licensed under a Creative Commons Attribution-NonCommercial 4.0 License. You’re free to copy and share this document, but not to sell it. You may not share source code provided with this document.