1
1
mirror of https://github.com/kanaka/mal.git synced 2024-11-11 08:56:41 +03:00
mal/plsql/env.sql
2016-05-22 00:16:02 -06:00

149 lines
4.1 KiB
SQL

-- ---------------------------------------------------------
-- env.sql
CREATE OR REPLACE TYPE env_item FORCE AS OBJECT (
key varchar2(256),
val integer
) FINAL;
/
CREATE OR REPLACE TYPE env_data FORCE IS TABLE OF env_item;
/
CREATE OR REPLACE TYPE env_T FORCE AS OBJECT (
idx integer,
outer_idx integer,
data env_data
);
/
CREATE OR REPLACE TYPE env_mem_T FORCE IS TABLE OF env_T;
/
CREATE OR REPLACE PACKAGE env_pkg IS
TYPE env_entry IS TABLE OF integer INDEX BY varchar2(256);
TYPE env_entry_table IS TABLE OF env_entry;
FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
eeT IN OUT NOCOPY env_entry_table,
outer_idx integer DEFAULT NULL)
RETURN integer;
FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
eeT IN OUT NOCOPY env_entry_table,
outer_idx integer,
binds integer,
exprs mal_vals)
RETURN integer;
FUNCTION env_set(M IN OUT NOCOPY types.mal_table,
eeT IN OUT NOCOPY env_entry_table,
eidx integer,
key integer,
val integer) RETURN integer;
FUNCTION env_find(M IN OUT NOCOPY types.mal_table,
eeT env_entry_table,
eidx integer,
key integer) RETURN integer;
FUNCTION env_get(M IN OUT NOCOPY types.mal_table,
eeT env_entry_table,
eidx integer,
key integer) RETURN integer;
END env_pkg;
/
show errors;
CREATE OR REPLACE PACKAGE BODY env_pkg IS
FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
eeT IN OUT NOCOPY env_entry_table,
outer_idx integer DEFAULT NULL)
RETURN integer IS
eidx integer;
BEGIN
eeT.EXTEND();
eidx := eeT.COUNT();
eeT(eidx)('**OUTER**') := outer_idx;
RETURN eidx;
END;
FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
eeT IN OUT NOCOPY env_entry_table,
outer_idx integer,
binds integer,
exprs mal_vals)
RETURN integer IS
eidx integer;
i integer;
bs mal_vals;
BEGIN
eeT.EXTEND();
eidx := eeT.COUNT();
eeT(eidx)('**OUTER**') := outer_idx;
IF binds IS NOT NULL THEN
bs := TREAT(M(binds) AS mal_seq_T).val_seq;
FOR i IN 1..bs.COUNT LOOP
IF TREAT(M(bs(i)) AS mal_str_T).val_str = '&' THEN
eeT(eidx)(TREAT(M(bs(i+1)) AS mal_str_T).val_str) :=
types.slice(M, exprs, i-1);
EXIT;
ELSE
eeT(eidx)(TREAT(M(bs(i)) AS mal_str_T).val_str) :=
exprs(i);
END IF;
END LOOP;
END IF;
RETURN eidx;
END;
FUNCTION env_set(M IN OUT NOCOPY types.mal_table,
eeT IN OUT NOCOPY env_entry_table,
eidx integer,
key integer,
val integer) RETURN integer IS
k varchar2(256);
i integer;
cnt integer;
BEGIN
k := TREAT(M(key) AS mal_str_T).val_str;
eeT(eidx)(k) := val;
RETURN val;
END;
FUNCTION env_find(M IN OUT NOCOPY types.mal_table,
eeT env_entry_table,
eidx integer,
key integer) RETURN integer IS
k varchar2(256);
cnt integer;
BEGIN
k := TREAT(M(key) AS mal_str_T).val_str;
IF eeT(eidx).EXISTS(k) THEN
RETURN eidx;
ELSIF eeT(eidx)('**OUTER**') IS NOT NULL THEN
RETURN env_find(M, eeT, eeT(eidx)('**OUTER**'), key);
ELSE
RETURN NULL;
END IF;
END;
FUNCTION env_get(M IN OUT NOCOPY types.mal_table,
eeT env_entry_table,
eidx integer,
key integer) RETURN integer IS
found integer;
k varchar2(256);
BEGIN
found := env_find(M, eeT, eidx, key);
k := TREAT(M(key) AS mal_str_T).val_str;
IF found IS NOT NULL THEN
RETURN eeT(found)(k);
ELSE
raise_application_error(-20005,
'''' || k || ''' not found', TRUE);
END IF;
END;
END env_pkg;
/
show errors;