Skip to content

Commit

Permalink
Merge pull request #100 from xsnippet/diesel
Browse files Browse the repository at this point in the history
Initial database schema
  • Loading branch information
malor committed Jul 26, 2020
2 parents f09b3d3 + 83b315f commit 49b7cba
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 14 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ jobs:
toolchain: ${{ matrix.rust-version }}
override: true

- name: Install libpq (Windows)
if: matrix.os == 'windows-latest'
shell: bash
run: |
choco install postgresql12 --force --params '/Password:root'
echo '::add-path::C:\Program Files\PostgreSQL\12\bin'
echo '::add-path::C:\Program Files\PostgreSQL\12\lib'
- uses: actions-rs/cargo@v1
with:
command: test
Expand Down
133 changes: 119 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ categories = [
publish = false

[dependencies]
chrono = "0.4.13"
diesel = { version = "1.4.5", features = ["postgres"] }
rocket = "0.4.5"
rocket_contrib = {version = "0.4.5", features = ["json"]}
8 changes: 8 additions & 0 deletions diesel.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# For documentation on how to configure this file,
# see diesel.rs/guides/configuring-diesel-cli

[print_schema]
file = "src/storage/sql/schema.rs"

[migrations_directory]
dir = "src/storage/sql/migrations"
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@

#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate rocket;
#[macro_use]
extern crate rocket_contrib;

mod application;
mod routes;
mod storage;

fn main() {
let app = application::create_app();
Expand Down
1 change: 1 addition & 0 deletions src/storage/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod sql;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
DROP TABLE tags;
DROP TABLE changesets;
DROP TABLE snippets;
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
CREATE TABLE snippets (
-- an internal autoincrementing identifier used in foreign keys.
-- Normally not visible publicly, except for the case when it is
-- used for looking legacy snippets up by id
id SERIAL PRIMARY KEY,
-- a short unique snippet identifier visible to users
slug VARCHAR(32) NOT NULL,

title TEXT,
syntax TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL,

-- slugs must be unique (this will also automatically create a unique index)
CONSTRAINT uq_slug UNIQUE (slug)
);


-- will be used for pagination; slug guarantees uniqueness of the sorting key
CREATE INDEX snippets_created_at_slug ON snippets (created_at, slug);
CREATE INDEX snippets_updated_at_slug ON snippets (updated_at, slug);


CREATE TABLE changesets (
id SERIAL PRIMARY KEY,
snippet_id INTEGER NOT NULL,

-- numeric index used to determine the ordering of changesets for a given snippet
version INTEGER DEFAULT 0 NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL,

-- there can be multiple changesets per snippet
CONSTRAINT fk_snippet FOREIGN KEY (snippet_id) REFERENCES snippets(id),
-- but each one is supposed to have a unique version number
CONSTRAINT uq_version UNIQUE (snippet_id, version),
-- sanity check: do not allow empty changesets
CONSTRAINT check_not_empty CHECK (LENGTH(content) > 0),
-- sanity check: version numbers are non-negative integers
CONSTRAINT check_non_negative_version CHECK (version >= 0)
);


-- tags could have been associated with snippets as M:M via an auxiliary table,
-- but Diesel only supports child-parent associations, so let's do that instead
CREATE TABLE tags (
id SERIAL PRIMARY KEY,
snippet_id INTEGER NOT NULL,

value TEXT NOT NULL,

-- there can be multiple tags per snippet
CONSTRAINT fk_snippet FOREIGN KEY (snippet_id) REFERENCES snippets(id),
-- do not allow to abuse the tags for storing too much data
CONSTRAINT check_length CHECK (LENGTH(value) < 128),
-- do not allow repeated tags per snippet
CONSTRAINT uq_snippet_tag UNIQUE (snippet_id, value)
);
1 change: 1 addition & 0 deletions src/storage/sql/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod schema;
36 changes: 36 additions & 0 deletions src/storage/sql/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// @generated automatically by Diesel CLI.

diesel::table! {
changesets (id) {
id -> Int4,
snippet_id -> Int4,
version -> Int4,
content -> Text,
created_at -> Timestamptz,
updated_at -> Timestamptz,
}
}

diesel::table! {
snippets (id) {
id -> Int4,
slug -> Varchar,
title -> Nullable<Text>,
syntax -> Nullable<Text>,
created_at -> Timestamptz,
updated_at -> Timestamptz,
}
}

diesel::table! {
tags (id) {
id -> Int4,
snippet_id -> Int4,
value -> Text,
}
}

diesel::joinable!(changesets -> snippets (snippet_id));
diesel::joinable!(tags -> snippets (snippet_id));

diesel::allow_tables_to_appear_in_same_query!(changesets, snippets, tags,);

0 comments on commit 49b7cba

Please sign in to comment.