Skip to content

Commit f464991

Browse files
committed
🌱
0 parents  commit f464991

File tree

12 files changed

+327
-0
lines changed

12 files changed

+327
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target/
2+
**/*.rs.bk

Cargo.lock

+182
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "diesel-pg-timestamp-usage"
3+
version = "0.1.0"
4+
authors = ["Mars Hall"]
5+
6+
[dependencies]
7+
chrono = "0.4.0"
8+
diesel = { version = "1.0.0", features = ["chrono", "postgres"] }

README.md

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Timestamps with Diesel.rs & Postgres
2+
3+
Example using UTC timestamps with the Rust language database ORM [Diesel](https://diesel.rs).
4+
5+
🌱💚 *Please note, I am new to Rust. I could not find a clear example for this basic task, so here's what I figured out. No guarantees about correctness. Please [open an issue](https://github.com/mars/diesel-pg-timestamp-usage/issues) to give feedback. I'd love to find better ways to do this.*
6+
7+
## Requirements
8+
9+
* [Rust + Cargo](https://www.rust-lang.org)
10+
* [Postgres](https://www.postgresql.org/download/)
11+
* `cargo install diesel_cli`
12+
13+
## Usage
14+
15+
```bash
16+
export DATABASE_URL=postgres://postgres@localhost:5432/diesel-pg-timestamp-usage
17+
diesel setup
18+
cargo run
19+
```
20+
21+
## Original setup
22+
23+
```bash
24+
export DATABASE_URL=postgres://postgres@localhost:5432/diesel-pg-timestamp-usage
25+
diesel setup
26+
diesel migration generate create-example
27+
# Write code in `migrations/up.sql` & `down.sql`
28+
diesel migration run
29+
diesel migration redo
30+
diesel print-schema > src/schema.rs
31+
```

migrations/.gitkeep

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- This file was automatically created by Diesel to setup helper functions
2+
-- and other internal bookkeeping. This file is safe to edit, any future
3+
-- changes will be added to existing projects as new migrations.
4+
5+
DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass);
6+
DROP FUNCTION IF EXISTS diesel_set_updated_at();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-- This file was automatically created by Diesel to setup helper functions
2+
-- and other internal bookkeeping. This file is safe to edit, any future
3+
-- changes will be added to existing projects as new migrations.
4+
5+
6+
7+
8+
-- Sets up a trigger for the given table to automatically set a column called
9+
-- `updated_at` whenever the row is modified (unless `updated_at` was included
10+
-- in the modified columns)
11+
--
12+
-- # Example
13+
--
14+
-- ```sql
15+
-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW());
16+
--
17+
-- SELECT diesel_manage_updated_at('users');
18+
-- ```
19+
CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$
20+
BEGIN
21+
EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s
22+
FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl);
23+
END;
24+
$$ LANGUAGE plpgsql;
25+
26+
CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$
27+
BEGIN
28+
IF (
29+
NEW IS DISTINCT FROM OLD AND
30+
NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at
31+
) THEN
32+
NEW.updated_at := current_timestamp;
33+
END IF;
34+
RETURN NEW;
35+
END;
36+
$$ LANGUAGE plpgsql;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DROP TABLE IF EXISTS examples
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CREATE TABLE examples (
2+
id serial primary key,
3+
created_at timestamp not null,
4+
updated_at timestamp
5+
)

src/main.rs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
extern crate chrono;
2+
#[macro_use]
3+
extern crate diesel;
4+
5+
use chrono::prelude::{Utc};
6+
use diesel::prelude::*;
7+
use diesel::pg::PgConnection;
8+
use std::env;
9+
10+
pub mod schema;
11+
pub mod models;
12+
use self::models::{Example, NewExample};
13+
14+
fn main() {
15+
let postgres_url = env::var("DATABASE_URL")
16+
.expect("requires DATABASE_URL env var");
17+
let pg = PgConnection::establish(&postgres_url)
18+
.expect(&format!("Error connecting to {}", postgres_url));
19+
20+
let now = Utc::now().naive_utc();
21+
22+
let new_example = NewExample {
23+
created_at: now,
24+
updated_at: Some(now),
25+
};
26+
27+
let database_record = diesel::insert_into(schema::examples::table)
28+
.values(&new_example)
29+
.get_result::<Example>(&pg)
30+
.expect("Error saving new example");
31+
32+
println!("Inserted example: {:?}", database_record);
33+
}

src/models.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use super::schema::examples;
2+
use super::chrono;
3+
4+
#[derive(Insertable, Debug)]
5+
#[table_name="examples"]
6+
pub struct NewExample {
7+
pub created_at: chrono::NaiveDateTime,
8+
pub updated_at: Option<chrono::NaiveDateTime>,
9+
}
10+
11+
#[derive(Queryable, Debug)]
12+
pub struct Example {
13+
pub id: i32,
14+
pub created_at: chrono::NaiveDateTime,
15+
pub updated_at: Option<chrono::NaiveDateTime>,
16+
}

src/schema.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
table! {
2+
examples (id) {
3+
id -> Int4,
4+
created_at -> Timestamp,
5+
updated_at -> Nullable<Timestamp>,
6+
}
7+
}

0 commit comments

Comments
 (0)