diff options
-rw-r--r-- | rust/.env | 1 | ||||
-rw-r--r-- | rust/Cargo.lock | 192 | ||||
-rw-r--r-- | rust/Cargo.toml | 8 | ||||
-rw-r--r-- | rust/NOTES.txt | 19 | ||||
-rw-r--r-- | rust/README.md | 6 | ||||
-rw-r--r-- | rust/migrations/00000000000000_diesel_initial_setup/down.sql | 6 | ||||
-rw-r--r-- | rust/migrations/00000000000000_diesel_initial_setup/up.sql | 37 | ||||
-rw-r--r-- | rust/migrations/2018-05-12-001226_init/down.sql | 7 | ||||
-rw-r--r-- | rust/migrations/2018-05-12-001226_init/up.sql | 61 | ||||
-rw-r--r-- | rust/src/bin/show_creators.rs | 24 | ||||
-rw-r--r-- | rust/src/lib.rs | 18 | ||||
-rw-r--r-- | rust/src/schema.rs | 68 |
12 files changed, 447 insertions, 0 deletions
diff --git a/rust/.env b/rust/.env new file mode 100644 index 00000000..fb95c489 --- /dev/null +++ b/rust/.env @@ -0,0 +1 @@ +DATABASE_URL=postgres://fatcat:tactaf@localhost/fatcat_rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock new file mode 100644 index 00000000..01f61f34 --- /dev/null +++ b/rust/Cargo.lock @@ -0,0 +1,192 @@ +[[package]] +name = "aho-corasick" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "diesel" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel_derives 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pq-sys 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "diesel_derives" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dotenv" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fc" +version = "0.1.0" +dependencies = [ + "diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "dotenv 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.40" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pq-sys" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.12.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ucd-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vcpkg" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" +"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" +"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87" +"checksum diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24815a0c2094f2c8dafe74ab3b9e975892f44acbb94b4d4b4898025a7615efa4" +"checksum diesel_derives 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6471a2b637b414d3ee1504cf230409a550381c79204282f8fe06c527e4ae56be" +"checksum dotenv 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "400b347fe65ccfbd8f545c9d9a75d04b0caf23fec49aaa838a9a05398f94c019" +"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" +"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" +"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" +"checksum pq-sys 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9323a6ce484fc41174d40f80ba87af6247f86a7ba57856af68d3aa0c8642d2f0" +"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" +"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" +"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" +"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" +"checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5" +"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" +"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" +"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 00000000..c1175b79 --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "fc" +version = "0.1.0" +authors = ["Bryan Newbold <bnewbold@archive.org>"] + +[dependencies] +diesel = { version = "1.0.0", features = ["postgres"] } +dotenv = "0.9.0" diff --git a/rust/NOTES.txt b/rust/NOTES.txt new file mode 100644 index 00000000..7e6f33eb --- /dev/null +++ b/rust/NOTES.txt @@ -0,0 +1,19 @@ + +libs: +- iron_slog +- testing: keep it simple: iron-test + => if that is annoying, shiny? mockers if needed. +- sentry +- start with dotenv+clap, then config-rs? +- cadence (emits statsd) +- frank_jwt and JWT for (simple?) auth + +similar: +- https://github.com/DavidBM/templic-backend +- https://github.com/alexanderbanks/rust-api +- https://mgattozzi.com/diesel-powered-rocket +- https://www.reddit.com/r/rust/comments/8j1xbs/new_to_rust_and_gitlab_ci/ +- https://crate-ci.github.io/ + +"cool tools": +- cargo-watch diff --git a/rust/README.md b/rust/README.md new file mode 100644 index 00000000..1f2beb60 --- /dev/null +++ b/rust/README.md @@ -0,0 +1,6 @@ + +Things! + + sudo apt install libsqlite3-dev libpq-dev + + wget https://oss.sonatype.org/content/repositories/snapshots/io/swagger/swagger-codegen-cli/3.0.0-SNAPSHOT/swagger-codegen-cli-3.0.0-20180411.134218-60.jar diff --git a/rust/migrations/00000000000000_diesel_initial_setup/down.sql b/rust/migrations/00000000000000_diesel_initial_setup/down.sql new file mode 100644 index 00000000..a9f52609 --- /dev/null +++ b/rust/migrations/00000000000000_diesel_initial_setup/down.sql @@ -0,0 +1,6 @@ +-- This file was automatically created by Diesel to setup helper functions +-- and other internal bookkeeping. This file is safe to edit, any future +-- changes will be added to existing projects as new migrations. + +DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); +DROP FUNCTION IF EXISTS diesel_set_updated_at(); diff --git a/rust/migrations/00000000000000_diesel_initial_setup/up.sql b/rust/migrations/00000000000000_diesel_initial_setup/up.sql new file mode 100644 index 00000000..3400c7c5 --- /dev/null +++ b/rust/migrations/00000000000000_diesel_initial_setup/up.sql @@ -0,0 +1,37 @@ +-- This file was automatically created by Diesel to setup helper functions +-- and other internal bookkeeping. This file is safe to edit, any future +-- changes will be added to existing projects as new migrations. + + + + +-- Sets up a trigger for the given table to automatically set a column called +-- `updated_at` whenever the row is modified (unless `updated_at` was included +-- in the modified columns) +-- +-- # Example +-- +-- ```sql +-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW()); +-- +-- SELECT diesel_manage_updated_at('users'); +-- ``` +CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ +BEGIN + EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s + FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ +BEGIN + IF ( + NEW IS DISTINCT FROM OLD AND + NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at + ) THEN + NEW.updated_at := current_timestamp; + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + diff --git a/rust/migrations/2018-05-12-001226_init/down.sql b/rust/migrations/2018-05-12-001226_init/down.sql new file mode 100644 index 00000000..6c379b2f --- /dev/null +++ b/rust/migrations/2018-05-12-001226_init/down.sql @@ -0,0 +1,7 @@ + +DROP TABLE IF EXISTS editor CASCADE; +DROP TABLE IF EXISTS editgroup CASCADE; +DROP TABLE IF EXISTS changelog CASCADE; +DROP TABLE IF EXISTS creator_rev CASCADE; +DROP TABLE IF EXISTS creator_ident CASCADE; +DROP TABLE IF EXISTS creator_edit CASCADE; diff --git a/rust/migrations/2018-05-12-001226_init/up.sql b/rust/migrations/2018-05-12-001226_init/up.sql new file mode 100644 index 00000000..2933deef --- /dev/null +++ b/rust/migrations/2018-05-12-001226_init/up.sql @@ -0,0 +1,61 @@ +-- written for Postgres 9.6 with OSSP extension for UUIDs + +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + + +-- uuid_generate_v1mc: timestamp ordered, random MAC address +-- uuid_generate_v4: totally random + +-- NB: could use LIKE clause, or "composite types" + +CREATE TABLE editor ( + id BIGSERIAL PRIMARY KEY, + username TEXT NOT NULL, + is_admin BOOLEAN NOT NULL DEFAULT false, + active_editgroup_id BIGINT -- REFERENCES( editgroup(id) via ALTER below +); + +CREATE TABLE editgroup ( + id BIGSERIAL PRIMARY KEY, + extra_json JSON, + editor_id BIGSERIAL REFERENCES editor(id) NOT NULL, + description TEXT +); + +ALTER TABLE editor + ADD CONSTRAINT editor_editgroupid_fkey FOREIGN KEY (active_editgroup_id) + REFERENCES editgroup(id); + +CREATE TABLE changelog ( + id BIGSERIAL PRIMARY KEY, + editgroup_id BIGINT REFERENCES editgroup(id) NOT NULL, + timestamp TIMESTAMP WITHOUT TIME ZONE DEFAULT now() +); + +CREATE TABLE creator_rev ( + id BIGSERIAL PRIMARY KEY, + extra_json JSON, + + name TEXT, + orcid TEXT +); + +-- Could denormalize a "is_live" flag into revision tables, to make indices +-- more efficient +CREATE INDEX creator_rev_orcid_idx ON creator_rev(orcid) WHERE orcid IS NOT NULL; + +CREATE TABLE creator_ident ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + is_live BOOL NOT NULL DEFAULT false, + rev_id BIGINT REFERENCES creator_rev(id), + redirect_id UUID REFERENCES creator_ident(id) +); + +CREATE TABLE creator_edit ( + id BIGSERIAL PRIMARY KEY, + extra_json JSON, + ident_id UUID REFERENCES creator_ident(id) NOT NULL, + rev_id BIGINT REFERENCES creator_rev(id), + redirect_id UUID REFERENCES creator_ident(id), + editgroup_id BIGINT REFERENCES editgroup(id) NOT NULL +); diff --git a/rust/src/bin/show_creators.rs b/rust/src/bin/show_creators.rs new file mode 100644 index 00000000..160ca3c7 --- /dev/null +++ b/rust/src/bin/show_creators.rs @@ -0,0 +1,24 @@ + +extern crate fc; +extern crate diesel; + +use self::fatcat_rs::*; +use self::models::*; +use self::diesel::prelude::*; + +fn main() { + use diesel_demo::schema::creators::dsl::*; + + let connection = establish_connection(); + let results = creators.filter(published.eq(true)) + .limit(5) + .load::<CreatorRev>(&connection) + .expect("Error loading creators"); + + println!("Displaying {} creators", results.len()); + for creator in results { + println!("{}", creator.title); + println!("----------\n"); + println!("{}", creator.body); + } +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs new file mode 100644 index 00000000..679b9ed3 --- /dev/null +++ b/rust/src/lib.rs @@ -0,0 +1,18 @@ + +#[macro_use] +extern crate diesel; +extern crate dotenv; + +use diesel::prelude::*; +use diesel::pg::PgConnection; +use dotenv::dotenv; +use std::env; + +pub fn establish_connection() -> PgConnection { + dotenv().ok(); + + let database_url = env::var("DATABASE_URL") + .expect("DATABASE_URL must be set"); + PgConnection::establish(&database_url) + .expect(&format!("Error connecting to {}", database_url)) +} diff --git a/rust/src/schema.rs b/rust/src/schema.rs new file mode 100644 index 00000000..7bef7dcd --- /dev/null +++ b/rust/src/schema.rs @@ -0,0 +1,68 @@ +table! { + changelog (id) { + id -> Int8, + editgroup_id -> Int8, + timestamp -> Nullable<Timestamp>, + } +} + +table! { + creator_edit (id) { + id -> Int8, + extra_json -> Nullable<Json>, + ident_id -> Uuid, + rev_id -> Nullable<Int8>, + redirect_id -> Nullable<Uuid>, + editgroup_id -> Int8, + } +} + +table! { + creator_ident (id) { + id -> Uuid, + is_live -> Bool, + rev_id -> Nullable<Int8>, + redirect_id -> Nullable<Uuid>, + } +} + +table! { + creator_rev (id) { + id -> Int8, + extra_json -> Nullable<Json>, + name -> Nullable<Text>, + orcid -> Nullable<Text>, + } +} + +table! { + editgroup (id) { + id -> Int8, + extra_json -> Nullable<Json>, + editor_id -> Int8, + description -> Nullable<Text>, + } +} + +table! { + editor (id) { + id -> Int8, + username -> Text, + is_admin -> Bool, + active_editgroup_id -> Nullable<Int8>, + } +} + +joinable!(changelog -> editgroup (editgroup_id)); +joinable!(creator_edit -> creator_rev (rev_id)); +joinable!(creator_edit -> editgroup (editgroup_id)); +joinable!(creator_ident -> creator_rev (rev_id)); + +allow_tables_to_appear_in_same_query!( + changelog, + creator_edit, + creator_ident, + creator_rev, + editgroup, + editor, +); |