Changeset 22

Show
Ignore:
Timestamp:
09/03/08 08:55:33 (3 years ago)
Author:
fumanchu
Message:

Added __create__, __record__, __iter__, __attributes__, and __len__ to global records. Moved the 'attributes' function into the test schema.

Location:
trunk/epic
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/epic/epic.sql

    r21 r22  
    244244 
    245245 
     246-- Note this is in the public schema!! 
     247CREATE OR REPLACE FUNCTION _global_record(tablename text, creator text) RETURNS record AS $$ 
     248DECLARE 
     249  result         record; 
     250  record_stmt    text; 
     251BEGIN 
     252  EXECUTE 'SELECT NULL::text AS __name__, NULL::text AS __create__, ' 
     253       || 'NULL::text AS __record__, NULL::text AS __iter__, ' 
     254       || 'NULL::text AS __attributes__, 0::int AS __len__, ' 
     255       || '* FROM ' || tablename || ' LIMIT 1' INTO result; 
     256   
     257  -- We add these values outside the EXECUTE in case the TEMP table has no rows. 
     258  result.__name__ := tablename; 
     259  result.__create__ := creator; 
     260  result.__record__ := 'SELECT * FROM _global_record(''' || tablename || ''', ''' || creator || ''')'; 
     261  result.__iter__ := 'SELECT * FROM ' || tablename; 
     262  result.__attributes__ := 'SELECT attname FROM test.attributes(''' || tablename || ''')'; 
     263  EXECUTE 'SELECT COUNT(*) FROM ' || tablename INTO result.__len__; 
     264   
     265  RETURN result; 
     266END; 
     267$$ LANGUAGE plpgsql; 
     268 
     269 
     270-- Note this is in the public schema!! 
    246271CREATE OR REPLACE FUNCTION global(call text) RETURNS record AS $$ 
    247272-- Stores the given call's output in a TEMP table, and returns it as a record. 
     
    251276--  
    252277-- The returned record includes the following additional attributes: 
    253 --   * tablename (text): The complete name of the TEMP table. This allows you 
    254 --       to pass my_record_var.tablename to functions that take a 'call text' 
    255 --       argument, such as assert_column, assert_values, and assert_empty 
    256 --       (since no procedural languages support passing records as args). 
     278--   * __name__ (text): The complete name of the TEMP table. This allows you 
     279--       to pass g.__name__ to functions that take a 'call text' argument, 
     280--       such as assert_column, assert_values, and assert_empty (since no 
     281--       procedural languages support passing records as args). 
     282--   * __create__ (text): The SQL statement used to construct the table. 
     283--   * __record__ (text): The SQL statement used to construct the returned record. 
     284--       Use this to copy the returned record (perhaps in another function). 
     285--       Example: EXECUTE g.__record__ INTO g2; 
     286--   * __iter__ (text): An SQL string to SELECT * FROM the TEMP table. 
     287--       Example: FOR record IN EXECUTE g.__iter__ 
     288--   * __attributes__ (text): The SQL string for TEMP table column names. 
     289--       Example: FOR colname IN EXECUTE g.__attributes__ 
     290--   * __len__ (int): The number of rows in the TEMP table. This value 
     291--       is NOT updated if you change the table after its creation. 
    257292DECLARE 
    258293  tablename      text; 
     294  creator        text; 
    259295  result         record; 
    260296BEGIN 
    261297  tablename := '_global_' || nextval('_global_ids'); 
    262   EXECUTE 'CREATE TEMP TABLE ' || tablename || ' AS ' || test.statement(call); 
    263   EXECUTE 'SELECT ''' || tablename || '''::text AS tablename, * FROM ' || tablename || ' LIMIT 1' INTO result; 
    264   IF result.tablename IS NULL THEN 
    265     -- Our temp table has no rows, so our tablename wasn't selected either. 
    266     result.tablename := tablename; 
    267   END IF; 
     298  creator := test.statement(call); 
     299  EXECUTE 'CREATE TEMP TABLE ' || tablename || ' AS ' || creator; 
     300  result := _global_record(tablename, creator); 
    268301  RETURN result; 
    269302END; 
     
    271304 
    272305 
    273 CREATE OR REPLACE FUNCTION attributes(tablename text) RETURNS SETOF pg_attribute AS $$ 
     306CREATE OR REPLACE FUNCTION test.attributes(tablename text) RETURNS SETOF pg_attribute AS $$ 
    274307DECLARE 
    275308  rec      record; 
  • trunk/epic/test/test_globals.sql

    r16 r22  
    1212  PERFORM test.assert_equal(rec.nspname, 'test'); 
    1313   
    14   -- The returned record MUST possess a .tablename attribute. 
    15   PERFORM test.assert(rec.tablename LIKE E'\_global\_%', rec.tablename || ' not like _global'); 
     14  -- The returned record MUST possess a .__name__ attribute. 
     15  PERFORM test.assert(rec.__name__ LIKE E'\_global\_%', rec.__name__ || ' not like _global'); 
    1616   
    17   -- The tablename MUST reference a temporary table with the same fields. 
    18   EXECUTE 'SELECT * FROM ' || rec.tablename INTO trec; 
     17  -- The .__name__ MUST reference a temporary table with the same fields. 
     18  EXECUTE 'SELECT * FROM ' || rec.__name__ INTO trec; 
    1919  PERFORM test.assert_equal(trec.nspname, 'test'); 
    2020  PERFORM test.assert_equal(trec.nspowner, rec.nspowner); 
    2121  PERFORM test.assert_equal(trec.nspacl, rec.nspacl); 
    2222   
    23   RAISE EXCEPTION '%', rec.tablename; 
     23  -- The returned record MUST possess a .__create__ attribute. 
     24  PERFORM test.assert_equal(rec.__create__, 'SELECT * FROM pg_namespace WHERE nspname = ''test'''); 
     25   
     26  -- The returned record MUST possess a .__record__ attribute. 
     27  PERFORM test.assert_equal(rec.__record__, 
     28    'SELECT * FROM _global_record(''' || rec.__name__ || ''', ''' || rec.__create__ || ''')'); 
     29   
     30  -- The returned record MUST possess an .__iter__ attribute. 
     31  PERFORM test.assert_equal(rec.__iter__, 'SELECT * FROM ' || rec.__name__); 
     32  PERFORM test.assert_not_empty(rec.__iter__); 
     33   
     34  -- The returned record MUST possess an .__attributes__ attribute. 
     35  PERFORM test.assert_equal(rec.__attributes__, 'SELECT attname FROM test.attributes(''' || rec.__name__ || ''')'); 
     36  PERFORM test.assert_column(rec.__attributes__, ARRAY['nspname', 'nspowner', 'nspacl']); 
     37   
     38  -- The returned record MUST possess a .__len__ attribute. 
     39  PERFORM test.assert_equal(rec.__len__, 1); 
     40   
     41  -- Raise an exception to test deletion of the TEMP table ON COMMIT 
     42  RAISE EXCEPTION '%', rec.__name__; 
    2443END; 
    2544$$ LANGUAGE plpgsql;