Implement undo in by PL/pgSQL
This commit is contained in:
@@ -1,22 +1,27 @@
|
||||
-- get_title()
|
||||
create function get_title() returns text as
|
||||
create function tj.get_title() returns text as
|
||||
$$
|
||||
select value from title;
|
||||
$$ language sql;
|
||||
declare
|
||||
title text;
|
||||
begin
|
||||
select value into title from tj.title;
|
||||
return title;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
-- update_title()
|
||||
create function update_title(new_title text) returns void as
|
||||
create function tj.set_title(new_title text) returns void as
|
||||
$$
|
||||
declare
|
||||
old_title text;
|
||||
redo text;
|
||||
undo text;
|
||||
begin
|
||||
select get_title() into old_title;
|
||||
update title set value = new_title where value = old_title;
|
||||
select tj.get_title() into old_title;
|
||||
update tj.title set value = new_title where value = old_title;
|
||||
|
||||
redo := concat('update title set value = ''', new_title, ''' where value = ''', old_title, '''');
|
||||
undo := concat('update title set value = ''', old_title, ''' where value = ''', new_title, '''');
|
||||
insert into operation values (default, redo, undo);
|
||||
redo := concat('update tj.title set value = ''', new_title, ''' where value = ''', old_title, '''');
|
||||
undo := concat('update tj.title set value = ''', old_title, ''' where value = ''', new_title, '''');
|
||||
perform tj.add_operation(redo, undo);
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
87
script/script/api/create/operation.sql
Normal file
87
script/script/api/create/operation.sql
Normal file
@@ -0,0 +1,87 @@
|
||||
create function tj.add_operation(redo text, undo text) returns void as
|
||||
$$
|
||||
declare
|
||||
parent_id int;
|
||||
curr_id int;
|
||||
begin
|
||||
select id into parent_id from tj.current_operation;
|
||||
insert into tj.operation (id, redo, undo, parent) values (default, redo, undo, parent_id);
|
||||
select max(id) into curr_id from tj.operation;
|
||||
update tj.current_operation set id = curr_id where id = parent_id;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create function tj.have_transaction() returns boolean as
|
||||
$$
|
||||
declare
|
||||
tran_count int;
|
||||
begin
|
||||
select count(*) into tran_count from tj.transaction_operation;
|
||||
return tran_count > 0;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create function tj.execute_undo(discard boolean) returns void as
|
||||
$$
|
||||
declare
|
||||
curr_id int;
|
||||
have_tran boolean;
|
||||
tran_id int;
|
||||
strict_mode boolean;
|
||||
undo_sql text;
|
||||
parent_id int;
|
||||
begin
|
||||
select id into curr_id from tj.current_operation;
|
||||
|
||||
select tj.have_transaction() into have_tran;
|
||||
if have_tran then
|
||||
select strict into strict_mode from tj.transaction_operation;
|
||||
if strict_mode then
|
||||
return; -- strict mode disallow undo
|
||||
else
|
||||
select id into tran_id from tj.transaction_operation;
|
||||
if tran_id >= curr_id then
|
||||
return; -- # normal mode disallow undo start point, and there is foreign key constraint
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
select undo into undo_sql from tj.operation where id = curr_id;
|
||||
if undo_sql = '' then
|
||||
return;
|
||||
end if;
|
||||
|
||||
select parent into parent_id from tj.operation where id = curr_id;
|
||||
if discard then
|
||||
update tj.operation set redo_child = null where id = parent_id;
|
||||
else
|
||||
update tj.operation set redo_child = curr_id where id = parent_id;
|
||||
end if;
|
||||
|
||||
execute undo_sql;
|
||||
|
||||
update tj.current_operation set id = parent_id where id = curr_id;
|
||||
|
||||
if discard then
|
||||
delete from tj.transaction_operation where id = curr_id;
|
||||
delete from tj.snapshot_operation where id = curr_id;
|
||||
delete from tj.operation where id = curr_id;
|
||||
end if;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create function tj.undo() returns void as
|
||||
$$
|
||||
declare
|
||||
begin
|
||||
perform tj.execute_undo(false);
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create function tj.discard_undo() returns void as
|
||||
$$
|
||||
declare
|
||||
begin
|
||||
perform tj.execute_undo(true);
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
9
script/script/api/create/project.sql
Normal file
9
script/script/api/create/project.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
create function tj.have_project(in_name text) returns boolean as
|
||||
$$
|
||||
declare
|
||||
db_count int;
|
||||
begin
|
||||
select count(*) into db_count from pg_database where datname = in_name;
|
||||
return db_count > 0;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
3
script/script/api/drop/1.title.sql
Normal file
3
script/script/api/drop/1.title.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
drop function if exists tj.set_title;
|
||||
|
||||
drop function if exists tj.get_title;
|
||||
7
script/script/api/drop/operation.sql
Normal file
7
script/script/api/drop/operation.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
drop function if exists tj.discard_undo;
|
||||
drop function if exists tj.undo;
|
||||
drop function if exists tj.execute_undo;
|
||||
|
||||
drop function if exists tj.have_transaction;
|
||||
|
||||
drop function if exists tj.add_operation;
|
||||
6
script/script/api/plpgsql.sql
Normal file
6
script/script/api/plpgsql.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
create function xxx() returns void as
|
||||
$$
|
||||
declare
|
||||
begin
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
@@ -31,10 +31,14 @@ sql_create = [
|
||||
"table/create/26.labels.sql",
|
||||
"table/create/27.backdrop.sql",
|
||||
"table/create/28.end.sql",
|
||||
"table/create/operation.sql"
|
||||
"table/create/operation.sql",
|
||||
"api/create/operation.sql",
|
||||
"api/create/1.title.sql"
|
||||
]
|
||||
|
||||
sql_drop = [
|
||||
"api/drop/1.title.sql",
|
||||
"api/drop/operation.sql",
|
||||
"table/drop/operation.sql",
|
||||
"table/drop/28.end.sql",
|
||||
"table/drop/27.backdrop.sql",
|
||||
|
||||
Reference in New Issue
Block a user