From 69db29d9817583c5bbce3bc4c387b24ebc38dd6e Mon Sep 17 00:00:00 2001 From: "WQY\\qiong" Date: Sun, 9 Oct 2022 18:27:35 +0800 Subject: [PATCH] Try new operation table --- script/sql/api/1.title.sql | 37 ++++++++++++++ script/sql/api/operation.sql | 85 +++++++++++++++++++++++++++++++++ script/sql/create/operation.sql | 25 +++------- script/sql/drop/operation.sql | 2 - script/template.py | 11 ++++- 5 files changed, 139 insertions(+), 21 deletions(-) create mode 100644 script/sql/api/1.title.sql create mode 100644 script/sql/api/operation.sql diff --git a/script/sql/api/1.title.sql b/script/sql/api/1.title.sql new file mode 100644 index 0000000..4932779 --- /dev/null +++ b/script/sql/api/1.title.sql @@ -0,0 +1,37 @@ +drop function if exists get_title; + +create function get_title() returns text as +$$ +select value from title as result; +$$ +language sql; + + +drop function if exists set_title; + +create function set_title(new_value text) returns json as +$$ +declare + old_value text; + + redo_sql text; + undo_sql text; + redo_cs json; + undo_cs json; + +begin + select value into old_value from title; + + redo_sql = format('update title set value = ''%s''', new_value); + undo_sql = format('update title set value = ''%s''', old_value); + redo_cs = format('{"operation": "update", "type": "title", "value": "%s" }', new_value)::json; + undo_cs = format('{"operation": "update", "type": "title", "value": "%s" }', old_value)::json; + execute add_operation(redo_sql, undo_sql, redo_cs, undo_cs); + + execute redo_sql; + + return redo_cs; + +end; +$$ +language plpgsql; \ No newline at end of file diff --git a/script/sql/api/operation.sql b/script/sql/api/operation.sql new file mode 100644 index 0000000..d18234d --- /dev/null +++ b/script/sql/api/operation.sql @@ -0,0 +1,85 @@ +drop function if exists get_current_operation; + +create function get_current_operation() returns integer as +$$ +select id from current_operation as result; +$$ +language sql; + + +drop function if exists add_operation; + +create function add_operation(redo_sql text, undo_sql text, redo_cs json, undo_cs json) returns void as +$$ +declare + parent_id integer; + op_id integer; + +begin + parent_id := get_current_operation(); + + insert into operation (id, redo, undo, parent, redo_change_set, undo_change_set) + values (default, redo_sql, undo_sql, parent_id, redo_cs, undo_cs); + + select max(id) into op_id from operation; + + update current_operation set id = op_id where id = parent_id; + +end; +$$ +language plpgsql; + + +drop function if exists execute_undo; + +create function execute_undo(discard boolean) returns json as +$$ +#print_strict_params on + +declare + op_row operation%ROWTYPE; + +begin + select * into strict op_row from operation where id = get_current_operation(); + if op_row.undo = '' then + return '{}'::json; + end if; + + execute op_row.undo; + + -- update foreign key + update current_operation set id = op_row.parent where id = op_row.id; + + if discard then + -- update foreign key + update operation set redo_child = null where id = op_row.parent; + -- on delete cascade => child & snapshot + delete from operation where id = op_row.id; + else + update operation set redo_child = op_row.id where id = op_row.parent; + end if; + + return op_row.undo_change_set; + +end; +$$ +language plpgsql; + + +-- create function execute_redo() returns json as +-- $$ +-- #print_strict_params on +-- +-- declare +-- op_id integer; +-- redo_c integer; +-- redo_row operation%ROWTYPE; +-- +-- begin +-- op_id := get_current_operation(); +-- +-- select redo_child into redo_c from operation where id = op_id; +-- +-- end; +-- $$ +-- language plpgsql; \ No newline at end of file diff --git a/script/sql/create/operation.sql b/script/sql/create/operation.sql index 43f8771..d5a0a93 100644 --- a/script/sql/create/operation.sql +++ b/script/sql/create/operation.sql @@ -1,36 +1,25 @@ -create type api_operation as enum ('init', 'add', 'delete', 'update'); - create table operation ( id serial primary key , redo text not null , undo text not null -, parent integer references operation(id) -, redo_child integer references operation(id) -, api_id text not null -, api_op api_operation not null -, api_object_type text not null -, api_object_id text not null -, api_object_properties text[] +, parent integer references operation(id) on delete cascade +, redo_child integer references operation(id) -- must update before delete +, redo_change_set json +, undo_change_set json ); -insert into operation (id, redo, undo, api_id, api_op, api_object_type, api_object_id) values (0, '', '', '', 'init', '', ''); +insert into operation (id, redo, undo) values (0, '', ''); create table current_operation ( - id integer primary key references operation(id) + id integer primary key references operation(id) -- must update before delete ); insert into current_operation (id) values (0); create table snapshot_operation ( - id integer primary key references operation(id) + id integer primary key references operation(id) on delete cascade , tag text not null unique ); - -create table transaction_operation -( - id integer primary key references operation(id) -, strict boolean not null default false -); diff --git a/script/sql/drop/operation.sql b/script/sql/drop/operation.sql index 0dd5237..344215a 100644 --- a/script/sql/drop/operation.sql +++ b/script/sql/drop/operation.sql @@ -5,5 +5,3 @@ drop table if exists snapshot_operation; drop table if exists current_operation; drop table if exists operation; - -drop type if exists api_operation; diff --git a/script/template.py b/script/template.py index e6e34a8..448ab58 100644 --- a/script/template.py +++ b/script/template.py @@ -30,7 +30,12 @@ sql_create = [ "sql/create/26.labels.sql", "sql/create/27.backdrop.sql", "sql/create/28.end.sql", - "sql/create/operation.sql" + "sql/create/operation.sql", +] + +sql_api = [ + "sql/api/operation.sql", + "sql/api/1.title.sql" ] sql_drop = [ @@ -76,6 +81,10 @@ def create_template(): with open(sql, "r") as f: cur.execute(f.read()) print(f'executed {sql}') + for sql in sql_api: + with open(sql, "r") as f: + cur.execute(f.read()) + print(f'executed {sql}') conn.commit() def have_template():