diff --git a/script/script/api/create/1.title.sql b/script/script/api/create/1.title.sql index 31340b8..abbf5e6 100644 --- a/script/script/api/create/1.title.sql +++ b/script/script/api/create/1.title.sql @@ -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; diff --git a/script/script/api/create/operation.sql b/script/script/api/create/operation.sql new file mode 100644 index 0000000..ebb5edf --- /dev/null +++ b/script/script/api/create/operation.sql @@ -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; \ No newline at end of file diff --git a/script/script/api/create/project.sql b/script/script/api/create/project.sql new file mode 100644 index 0000000..50e8197 --- /dev/null +++ b/script/script/api/create/project.sql @@ -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; diff --git a/script/script/api/drop/1.title.sql b/script/script/api/drop/1.title.sql new file mode 100644 index 0000000..9bef302 --- /dev/null +++ b/script/script/api/drop/1.title.sql @@ -0,0 +1,3 @@ +drop function if exists tj.set_title; + +drop function if exists tj.get_title; \ No newline at end of file diff --git a/script/script/api/drop/operation.sql b/script/script/api/drop/operation.sql new file mode 100644 index 0000000..951fa22 --- /dev/null +++ b/script/script/api/drop/operation.sql @@ -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; \ No newline at end of file diff --git a/script/script/api/plpgsql.sql b/script/script/api/plpgsql.sql new file mode 100644 index 0000000..06c96e0 --- /dev/null +++ b/script/script/api/plpgsql.sql @@ -0,0 +1,6 @@ +create function xxx() returns void as +$$ +declare +begin +end; +$$ language plpgsql; \ No newline at end of file diff --git a/script/script/template.py b/script/script/template.py index 0b795b5..7ed9a98 100644 --- a/script/script/template.py +++ b/script/script/template.py @@ -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",