From b7c7e32d1d7f2e946aab34abdb963519fedd7dc6 Mon Sep 17 00:00:00 2001 From: Nicolas Duhamel Date: Wed, 10 Feb 2016 19:03:55 +0100 Subject: [PATCH] Add created and update column --- users.go | 28 ++++++++++++++++++++++++---- users_test.go | 18 +++++++++++++++++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/users.go b/users.go index aa5894f..5b15b0e 100644 --- a/users.go +++ b/users.go @@ -2,6 +2,7 @@ package users import ( "fmt" + "time" "github.com/jmoiron/sqlx" "gitlab.quimbo.fr/odwrtw/canape-sql/random" @@ -10,19 +11,30 @@ import ( const usersCreate = ` CREATE TABLE users ( id SERIAL PRIMARY KEY, - name text NOT NULL UNIQUE + name text NOT NULL UNIQUE, + updated timestamp DEFAULT current_timestamp, + created timestamp DEFAULT current_timestamp ); CREATE TABLE tokens ( id SERIAL, value text NOT NULL UNIQUE, - users_id integer REFERENCES users (id) ON DELETE CASCADE + users_id integer REFERENCES users (id) ON DELETE CASCADE, + updated timestamp DEFAULT current_timestamp, + created timestamp DEFAULT current_timestamp ); + +CREATE OR REPLACE FUNCTION update_modified_column() +RETURNS TRIGGER AS $$ +BEGIN NEW.updated = now(); RETURN NEW; END; $$ language 'plpgsql'; + +CREATE TRIGGER update_users BEFORE UPDATE ON users FOR EACH ROW EXECUTE PROCEDURE update_modified_column(); +CREATE TRIGGER update_tokens BEFORE UPDATE ON tokens FOR EACH ROW EXECUTE PROCEDURE update_modified_column(); ` const ( addUserQuery = `INSERT INTO users (name) VALUES ($1) RETURNING id;` getUserQuery = `SELECT * FROM users WHERE name=$1;` - updateUserQuery = `UPDATE users SET (name)=(:name);` + updateUserQuery = `UPDATE users SET name=$1 RETURNING *;` deleteUseQuery = `DELETE FROM users WHERE id=:id;` addTokenQuery = `INSERT INTO tokens (value, users_id) VALUES ($1, $2) RETURNING id;` @@ -31,14 +43,22 @@ const ( deleteTokenQuery = `DELETE FROM tokens WHERE users_id=$1 AND value=$2;` ) +// BaseTable have to be embeded in all your struct which reflect a table +type BaseTable struct { + Updated time.Time + Created time.Time +} + // User represents an user type User struct { + BaseTable ID int Name string } // Token represents a token type Token struct { + BaseTable ID int Value string } @@ -66,7 +86,7 @@ func (u *User) Add(q sqlx.Queryer) error { // Update user on database or raise an error func (u *User) Update(ex *sqlx.DB) error { - _, err := ex.NamedExec(updateUserQuery, u) + err := ex.Get(u, updateUserQuery, u.Name) if err != nil { return err } diff --git a/users_test.go b/users_test.go index 700bfcf..18fd064 100644 --- a/users_test.go +++ b/users_test.go @@ -13,7 +13,10 @@ import ( const drop = ` DROP TABLE tokens; -DROP TABLE users;` +DROP TABLE users; + +DROP FUNCTION update_modified_column(); +` var db *sqlx.DB @@ -182,3 +185,16 @@ func TestTokenCheck(t *testing.T) { }) } + +func TestAutoUpdateCols(t *testing.T) { + sqltest.RunWithSchema(db, usersCreate, drop, t, func(db *sqlx.DB, t *testing.T) { + u := &User{Name: "plop"} + u.Add(db) + u.Name = "toto" + u.Update(db) + + if !u.Created.Before(u.Updated) { + t.Fatalf("colum updated not auto updated on table users") + } + }) +}