As previously stated, the code layer is the only schema that has access to the data and the user schema is the only schema allowed to access the code layer. The code schema is a schema that only contains a set of stored procedures, which have limited access to the data schema.
The package below contains two simple stored procedures for reading and writing events to our purchase events example; remember that these have been simplified for clarity.
The Package Specification
CREATE OR REPLACE PACKAGE ORDERS_CODE.purchase_events AS PROCEDURE update_purchase_events(p_purchase_code IN VARCHAR2,p_event_code IN NUMBER,p_event_date TIMESTAMP); FUNCTION read_order_events(p_purchase_code IN VARCHAR2) RETURN SYS_REFCURSOR; END purchase_events; / show errors;
The Package Body
Having defined the package specification, the package body follows:CREATE OR REPLACE PACKAGE BODY ORDERS_CODE.purchase_events IS -- -- Simple proc that inserts an event into the event table. -- Error handling removed for simplicity -- PROCEDURE update_purchase_events(p_purchase_code IN VARCHAR2,p_event_code IN NUMBER,p_event_date TIMESTAMP) IS BEGIN INSERT INTO orders_purchase_events (pk,purchase_code,event_code,event_date) VALUES(ORDERS_CODE.ORDERS_EVENT_SEQUENCE.nextVal,p_purchase_code,p_event_code,p_event_date); END update_purchase_events; -- -- Function that reads data from the PURCHASE events tables. -- Returning all the events for a given purchase code. -- Error handling removed for simplicity -- FUNCTION read_order_events(p_purchase_code IN VARCHAR2) RETURN SYS_REFCURSOR AS v_cursor SYS_REFCURSOR; BEGIN OPEN v_cursor FOR SELECT e.purchase_code,c.event_type,e.event_date FROM orders_purchase_events e, orders_purchase_eventcodes c, WHERE c.event_code = e.event_code AND e.purchase_code = p_purchase_code; RETURN v_cursor; END read_order_events; END purchase_events; / show errors
Example of the Three Tier Schema - Completing the User Tier
The last step in completing our three tier database is to allow the user schema to access our code.GRANT EXECUTE ON ORDERS_CODE.purchase_events TO ORDERS_USER; CREATE OR REPLACE PUBLIC SYNONYM purchase_events for orders_code.purchase_events; /The very last step is giving our application access to the user schema. This is usually by creating a data source in our web or application server, which is used by our application.
Some Organisation
One of the negative aspects of this arrangement is its complexity. One way to negate this is to employ a strict system of structuring your database files.The system suggested below shares the data, code and user schemas between six separate files for clarity. These are:
<package name>.sql
- which contains the data layer construction<package name>.pks
- which contains the package specification<package name>.pkb
- which contains the package code body<package name>.grants
- which contains the privileges granted to other users<package name>.synonyms
- which contains the appropriate PUBLIC synonym.<package name>.order
@@<package name>.pks @@<package name>.pkb @@<package name>.grants @@<package name>.synonyms
And Finally...
In a well defined and correctly architected system, you can see how splitting your database into three separate schemas can aid system security: your webserver only knows about the user schema, the user schema is only allowed to access the stored procedures of the code schema, and finally, the code schema has limited access to the data that’s buried at the heart of your system.Posts in this series:
No comments:
Post a comment