-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Usability/flexibility of API #6
Comments
In order to enable generation of random rows something like the below could be used. There is very little usability coming with procedures using Likewise, the get_[column_name] are of little value as the read_row gives you access to both whole row as well as individual attribute so you can write Please let me know what you think about implementing something like below. CREATE OR REPLACE PACKAGE employees_api
IS
/**
* This is the API for the table EMPLOYEES.
*
* GENERATION OPTIONS
* - must be in the lines 5-25 to be reusable by the generator
* - DO NOT TOUCH THIS until you know what you do - read the
* docs under github.com/OraMUC/table-api-generator ;-)
* <options
* generator=OM_TAPIGEN
* generator_version=0.4.0
* generator_action=GET_CODE
* generated_at=2017-05-27 13:05:19
* generated_by=HR
* p_table_name=EMPLOYEES
* p_reuse_existing_api_params=TRUE
* p_col_prefix_in_method_names=TRUE
* p_enable_insertion_of_rows=TRUE
* p_enable_update_of_rows=FALSE
* p_enable_deletion_of_rows=TRUE
* p_enable_generic_change_log=FALSE
* p_enable_dml_view=FALSE
* p_sequence_name=EMPLOYEES_SEQ/>
*
* This API provides DML functionality that can be easily called from APEX.
* Target of the table API is to encapsulate the table DML source code for
* security (UI schema needs only the execute right for the API and the
* read/write right for the EMPLOYEES_dml_v, tables can be hidden in
* extra data schema) and easy readability of the business logic (all DML is
* then written in the same style). For APEX automatic row processing like
* tabular forms you can optionally use the EMPLOYEES_dml_v, which has
* an instead of trigger who is also calling the EMPLOYEES_api.
*/
----------------------------------------
FUNCTION row_exists (p_employee_id IN employees.employee_id%TYPE)
RETURN BOOLEAN;
----------------------------------------
FUNCTION row_exists_yn (p_employee_id IN employees.employee_id%TYPE)
RETURN VARCHAR2;
----------------------------------------
FUNCTION get_a_row RETURN employees%ROWTYPE;
----------------------------------------
FUNCTION create_row (
p_employee_id IN employees.employee_id%TYPE DEFAULT get_a_row().employee_id,
p_first_name IN employees.first_name%TYPE DEFAULT get_a_row().first_name,
p_last_name IN employees.last_name%TYPE DEFAULT get_a_row().last_name,
p_email IN employees.email%TYPE DEFAULT get_a_row().email,
p_phone_number IN employees.phone_number%TYPE DEFAULT get_a_row().phone_number,
p_hire_date IN employees.hire_date%TYPE DEFAULT get_a_row().hire_date,
p_job_id IN employees.job_id%TYPE DEFAULT get_a_row().job_id,
p_salary IN employees.salary%TYPE DEFAULT get_a_row().salary,
p_commission_pct IN employees.commission_pct%TYPE DEFAULT get_a_row().commission_pct,
p_manager_id IN employees.manager_id%TYPE DEFAULT get_a_row().manager_id,
p_department_id IN employees.department_id%TYPE DEFAULT get_a_row().department_id
)
RETURN employees%ROWTYPE;
----------------------------------------
PROCEDURE create_row (
p_employee_id IN employees.employee_id%TYPE DEFAULT get_a_row().employee_id,
p_first_name IN employees.first_name%TYPE DEFAULT get_a_row().first_name,
p_last_name IN employees.last_name%TYPE DEFAULT get_a_row().last_name,
p_email IN employees.email%TYPE DEFAULT get_a_row().email,
p_phone_number IN employees.phone_number%TYPE DEFAULT get_a_row().phone_number,
p_hire_date IN employees.hire_date%TYPE DEFAULT get_a_row().hire_date,
p_job_id IN employees.job_id%TYPE DEFAULT get_a_row().job_id,
p_salary IN employees.salary%TYPE DEFAULT get_a_row().salary,
p_commission_pct IN employees.commission_pct%TYPE DEFAULT get_a_row().commission_pct,
p_manager_id IN employees.manager_id%TYPE DEFAULT get_a_row().manager_id,
p_department_id IN employees.department_id%TYPE DEFAULT get_a_row().department_id
);
----------------------------------------
FUNCTION create_row (p_row IN employees%ROWTYPE)
RETURN employees%ROWTYPE;
----------------------------------------
PROCEDURE create_row (p_row IN employees%ROWTYPE);
----------------------------------------
FUNCTION read_row (p_employee_id IN employees.employee_id%TYPE DEFAULT NULL)
RETURN employees%ROWTYPE;
----------------------------------------
PROCEDURE delete_row (p_employee_id IN employees.employee_id%TYPE);
----------------------------------------
END employees_api;
/ CREATE OR REPLACE PACKAGE BODY employees_api
IS
----------------------------------------
FUNCTION row_exists (p_employee_id IN employees.employee_id%TYPE)
RETURN BOOLEAN
IS
v_return BOOLEAN := FALSE;
BEGIN
FOR i IN (
SELECT 1
FROM employees
WHERE employee_id = p_employee_id
) LOOP
v_return := TRUE;
END LOOP;
RETURN v_return;
END;
----------------------------------------
FUNCTION row_exists_yn (p_employee_id IN employees.employee_id%TYPE)
RETURN VARCHAR2
IS
BEGIN
RETURN CASE WHEN row_exists (p_employee_id => p_employee_id) THEN 'Y' ELSE 'N' END;
END;
----------------------------------------
FUNCTION create_row (
p_employee_id IN employees.employee_id%TYPE DEFAULT get_a_row().employee_id,
p_first_name IN employees.first_name%TYPE DEFAULT get_a_row().first_name,
p_last_name IN employees.last_name%TYPE DEFAULT get_a_row().last_name,
p_email IN employees.email%TYPE DEFAULT get_a_row().email,
p_phone_number IN employees.phone_number%TYPE DEFAULT get_a_row().phone_number,
p_hire_date IN employees.hire_date%TYPE DEFAULT get_a_row().hire_date,
p_job_id IN employees.job_id%TYPE DEFAULT get_a_row().job_id,
p_salary IN employees.salary%TYPE DEFAULT get_a_row().salary,
p_commission_pct IN employees.commission_pct%TYPE DEFAULT get_a_row().commission_pct,
p_manager_id IN employees.manager_id%TYPE DEFAULT get_a_row().manager_id,
p_department_id IN employees.department_id%TYPE DEFAULT get_a_row().department_id
)
RETURN employees%ROWTYPE
IS
v_pk employees.employee_id%TYPE;
v_row employees%ROWTYPE;
BEGIN
v_pk := COALESCE (p_employee_id, employees_seq.NEXTVAL);
INSERT INTO employees (
employee_id,
first_name,
last_name,
email,
phone_number,
hire_date,
job_id,
salary,
commission_pct,
manager_id,
department_id
)
VALUES (
v_pk,
p_first_name,
p_last_name,
p_email,
p_phone_number,
p_hire_date,
p_job_id,
p_salary,
p_commission_pct,
p_manager_id,
p_department_id
)
RETURNING employee_id,
first_name,
last_name,
email,
phone_number,
hire_date,
job_id,
salary,
commission_pct,
manager_id,
department_id
INTO v_row;
RETURN v_row;
END create_row;
----------------------------------------
PROCEDURE create_row (
p_employee_id IN employees.employee_id%TYPE DEFAULT get_a_row().employee_id,
p_first_name IN employees.first_name%TYPE DEFAULT get_a_row().first_name,
p_last_name IN employees.last_name%TYPE DEFAULT get_a_row().last_name,
p_email IN employees.email%TYPE DEFAULT get_a_row().email,
p_phone_number IN employees.phone_number%TYPE DEFAULT get_a_row().phone_number,
p_hire_date IN employees.hire_date%TYPE DEFAULT get_a_row().hire_date,
p_job_id IN employees.job_id%TYPE DEFAULT get_a_row().job_id,
p_salary IN employees.salary%TYPE DEFAULT get_a_row().salary,
p_commission_pct IN employees.commission_pct%TYPE DEFAULT get_a_row().commission_pct,
p_manager_id IN employees.manager_id%TYPE DEFAULT get_a_row().manager_id,
p_department_id IN employees.department_id%TYPE DEFAULT get_a_row().department_id
)
IS
v_row employees%ROWTYPE;
BEGIN
v_row :=
create_row (
p_employee_id => p_employee_id,
p_first_name => p_first_name,
p_last_name => p_last_name,
p_email => p_email,
p_phone_number => p_phone_number,
p_hire_date => p_hire_date,
p_job_id => p_job_id,
p_salary => p_salary,
p_commission_pct => p_commission_pct,
p_manager_id => p_manager_id,
p_department_id => p_department_id
);
END create_row;
----------------------------------------
FUNCTION create_row (p_row IN employees%ROWTYPE)
RETURN employees%ROWTYPE
IS
v_row employees%ROWTYPE;
BEGIN
v_row :=
create_row (
p_employee_id => p_row.employee_id,
p_first_name => p_row.first_name,
p_last_name => p_row.last_name,
p_email => p_row.email,
p_phone_number => p_row.phone_number,
p_hire_date => p_row.hire_date,
p_job_id => p_row.job_id,
p_salary => p_row.salary,
p_commission_pct => p_row.commission_pct,
p_manager_id => p_row.manager_id,
p_department_id => p_row.department_id
);
RETURN v_row;
END create_row;
----------------------------------------
PROCEDURE create_row (p_row IN employees%ROWTYPE)
IS
v_row employees%ROWTYPE;
BEGIN
v_row :=
create_row (
p_employee_id => p_row.employee_id,
p_first_name => p_row.first_name,
p_last_name => p_row.last_name,
p_email => p_row.email,
p_phone_number => p_row.phone_number,
p_hire_date => p_row.hire_date,
p_job_id => p_row.job_id,
p_salary => p_row.salary,
p_commission_pct => p_row.commission_pct,
p_manager_id => p_row.manager_id,
p_department_id => p_row.department_id
);
END create_row;
----------------------------------------
FUNCTION read_row (p_employee_id IN employees.employee_id%TYPE DEFAULT NULL)
RETURN employees%ROWTYPE
IS
v_row employees%ROWTYPE;
BEGIN
IF p_employee_id IS NOT NULL THEN
SELECT *
INTO v_row
FROM employees
WHERE employee_id = p_employee_id;
ELSE
SELECT *
INTO v_row
FROM employees
WHERE ROWNUM = 1;
END IF;
RETURN v_row;
END read_row;
----------------------------------------
PROCEDURE delete_row (p_employee_id IN employees.employee_id%TYPE)
IS
BEGIN
DELETE FROM employees
WHERE employee_id = p_employee_id;
END delete_row;
----------------------------------------
FUNCTION get_a_row RETURN employees%ROWTYPE
IS
v_row employees%ROWTYPE;
BEGIN
v_row.employee_id := employees_seq.nextval; --generated from SEQ
v_row.first_name := 'Chuck';
v_row.last_name := 'Norris';
v_row.email := substr(sys_guid(),1,25); --generged as there is a UK on that column
v_row.phone_number := '123';
v_row.hire_date := to_date('2017-05-27','YYYY-MM-DD');
v_row.job_id := 'FI_MGR';
v_row.salary := 123;
v_row.commission_pct := 0.01;
v_row.manager_id := null;
v_row.department_id := null;
RETURN v_row;
END;
END employees_api;
/ |
Hi Jacek, to answer some of your questions I edited the issue #6 (change questions from checkmark to ordered list)
I personally think this is a good idea. I had no idea that something like this is possible:
I can't find a generated procedure with such an out type in the example-api. Can you please make clear your question?
This function is created per unique key (overloeded) - I have such tables in some of my applications ;-)
I answered the behaviour a little bit in your issue #8. The column prefix is derived automatically - in the example below the it would be I know - you don't want the getter and setter at all, but this is another story ;-) CREATE TABLE "HR"."EMPLOYEES" (
"EMP_ID" NUMBER(6,0),
"EMP_FIRST_NAME" VARCHAR2(20 BYTE),
"EMP_LAST_NAME" VARCHAR2(25 BYTE),
"EMP_EMAIL" VARCHAR2(25 BYTE),
"EMP_PHONE_NUMBER" VARCHAR2(20 BYTE),
"EMP_HIRE_DATE" DATE,
"EMP_JOB_ID" VARCHAR2(10 BYTE),
"EMP_SALARY" NUMBER(8,2),
"EMP_COMMISSION_PCT" NUMBER(2,2),
"EMP_MANAGER_ID" NUMBER(6,0),
"EMP_DEPARTMENT_ID" NUMBER(4,0)
);
I personally prefer to have a special function called I find the idea to have a read_random_row function nice. Could be useful in other cases. And yes, you are right, the getter and setter are not that useful, but in some cases... ... in short, parameterizing this is a good idea and may be omitting this stuff is also ok because there is a alternative as you mentioned already with the row type and the dot notation... Good, that we currently in a early stage with the v0.4.1 ;-) I have to discuss many things with André now... Best regards |
Thanks for your answer, I've discovered some magic of PLSQL within last 2 years or so. |
I have few observations, nice to have features for the API.
%rowtype
parameter? Having the function seems sufficient and much more readable when you use it in your code.get_pk_by_unique_cols
, not sure what will happen if i have more than one set of unique cols. Can we have control over generation of those functions?p_col_prefix_in_method_names => FALSE
causes the generator to with error:You can reference procedure parameters with procedure name, that way you don't need to prefix column_name parameters. This will also let you avoid the common issue of variable name length > 30 char, when column name length = 30 char.
The text was updated successfully, but these errors were encountered: