diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ba819c43..6552d222 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,7 +35,10 @@ jobs: - run: npm install - name: "test images" - run: docker exec siro sh -c "PGSERVICE=siro_build /src/tests/official_sign_images.sh" + run: docker exec siro pytest + + - name: "test images" + run: docker exec siro sh -c "PGSERVICE=siro_build /src/test/official_sign_images.sh" - name: "schema lint" run: | diff --git a/.gitignore b/.gitignore index d90951a9..b6cf3688 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ *.orig .schemalintrc.js __pycache__ -*.qgs~ \ No newline at end of file +*.qgs~ +local_test.sh \ No newline at end of file diff --git a/data_model/demo_data/demo_data.sql b/data_model/demo_data/demo_data.sql deleted file mode 100644 index 4550b97c..00000000 --- a/data_model/demo_data/demo_data.sql +++ /dev/null @@ -1,40 +0,0 @@ --- Insert supports - -INSERT INTO siro_od.support(fk_support_type,fk_support_base_type,fk_status,geometry) -VALUES (1,1,1,ST_GeomFromText('POINT(2538388.0 1152589.8)',2056)); -INSERT INTO siro_od.support(id,fk_support_type,fk_support_base_type,fk_status,geometry) -VALUES ('00000000-0000-0000-0000-000000000001',1,1,1,ST_GeomFromText('POINT(2537954.42 1152523.14)',2056)); -INSERT INTO siro_od.support(fk_support_type,fk_support_base_type,fk_status,geometry) -VALUES (3,2,1,ST_GeomFromText('POINT(2538449.48 1152512.22)',2056)); - --- Insert frame - -INSERT INTO siro_od.frame(id,rank,fk_frame_type,fk_frame_fixing_type,double_sided,fk_status,fk_support) -VALUES ('00000000-0000-0000-ffff-000000000002',1,1,1,true,1,'00000000-0000-0000-0000-000000000001'); -INSERT INTO siro_od.frame(id,rank,fk_frame_type,fk_frame_fixing_type,double_sided,fk_status,fk_support) -VALUES ('00000000-0000-0000-ffff-000000000003',2,1,1,true,1,'00000000-0000-0000-0000-000000000001'); -INSERT INTO siro_od.frame(id,rank,fk_frame_type,fk_frame_fixing_type,double_sided,fk_status,fk_support) -VALUES ('00000000-0000-0000-ffff-000000000004',3,1,1,true,1,'00000000-0000-0000-0000-000000000001'); -INSERT INTO siro_od.frame(id,rank,fk_frame_type,fk_frame_fixing_type,double_sided,fk_status,fk_support) -VALUES ('00000000-0000-0000-ffff-000000000005',4,1,1,true,1,'00000000-0000-0000-0000-000000000001'); -INSERT INTO siro_od.frame(id,rank,fk_frame_type,fk_frame_fixing_type,double_sided,fk_status,fk_support) -VALUES ('00000000-0000-0000-ffff-000000000006',5,1,1,true,1,'00000000-0000-0000-0000-000000000001'); -INSERT INTO siro_od.frame(id,rank,fk_frame_type,fk_frame_fixing_type,double_sided,fk_status,fk_support) -VALUES ('00000000-0000-0000-ffff-000000000007',6,1,1,true,1,'00000000-0000-0000-0000-000000000001'); - --- Insert signs - -INSERT INTO siro_od.sign(id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,azimut,fk_frame) -VALUES ('00000000-0000-0000-eeee-000000000001',1,1,'1.01',1,1,20,'00000000-0000-0000-ffff-000000000002'); -INSERT INTO siro_od.sign(id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,azimut,fk_frame) -VALUES ('00000000-0000-0000-eeee-000000000002',1,1,'1.03',1,1,19,'00000000-0000-0000-ffff-000000000003'); -INSERT INTO siro_od.sign(id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,azimut,fk_frame) -VALUES ('00000000-0000-0000-eeee-000000000003',1,1,'1.25a',1,1,214,'00000000-0000-0000-ffff-000000000004'); -INSERT INTO siro_od.sign(id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,azimut,fk_frame) -VALUES ('00000000-0000-0000-eeee-000000000004',1,1,'1.30',1,1,210,'00000000-0000-0000-ffff-000000000005'); -INSERT INTO siro_od.sign(id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,azimut,fk_frame) -VALUES ('00000000-0000-0000-eeee-000000000005',1,1,'2.15.1',1,1,180,'00000000-0000-0000-ffff-000000000006'); -INSERT INTO siro_od.sign(id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,azimut,fk_frame) -VALUES ('00000000-0000-0000-eeee-000000000006',1,1,'2.16',1,1,180,'00000000-0000-0000-ffff-000000000007'); -INSERT INTO siro_od.sign(id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,azimut,fk_frame) -VALUES ('00000000-0000-0000-eeee-000000000007',2,1,'4.52',1,1,20,'00000000-0000-0000-ffff-000000000002'); diff --git a/data_model/ordinary_data/azimut.sql b/data_model/ordinary_data/azimut.sql new file mode 100644 index 00000000..0f2f5c35 --- /dev/null +++ b/data_model/ordinary_data/azimut.sql @@ -0,0 +1,11 @@ + + + +CREATE TABLE siro_od.azimut +( + id uuid PRIMARY KEY default uuid_generate_v1(), + fk_support uuid not null, + azimut smallint default 0, + CONSTRAINT fkey_od_support FOREIGN KEY (fk_support) REFERENCES siro_od.support (id) MATCH SIMPLE, + UNIQUE (fk_support, azimut) +); \ No newline at end of file diff --git a/data_model/ordinary_data/frame.sql b/data_model/ordinary_data/frame.sql index 43b01e2f..35c0e3e6 100644 --- a/data_model/ordinary_data/frame.sql +++ b/data_model/ordinary_data/frame.sql @@ -5,16 +5,17 @@ CREATE TABLE siro_od.frame ( id uuid PRIMARY KEY default uuid_generate_v1(), - rank int default 1, + fk_azimut uuid not null, + rank int default 1, -- TODO: get default fk_frame_type int, fk_frame_fixing_type int, - double_sided boolean, + double_sided boolean default true, fk_status int, - fk_support uuid, comment text, picture text, + CONSTRAINT fkey_od_azimut FOREIGN KEY (fk_azimut) REFERENCES siro_od.azimut (id) MATCH SIMPLE, CONSTRAINT fkey_vl_frame_type FOREIGN KEY (fk_frame_type) REFERENCES siro_vl.frame_type (id) MATCH SIMPLE, CONSTRAINT fkey_vl_status FOREIGN KEY (fk_status) REFERENCES siro_vl.status (id) MATCH SIMPLE, - CONSTRAINT fkey_support FOREIGN KEY (fk_support) REFERENCES siro_od.support (id) MATCH SIMPLE, - CONSTRAINT fkey_vl_frame_fixing_type FOREIGN KEY (fk_frame_fixing_type) REFERENCES siro_vl.frame_fixing_type (id) MATCH SIMPLE + CONSTRAINT fkey_vl_frame_fixing_type FOREIGN KEY (fk_frame_fixing_type) REFERENCES siro_vl.frame_fixing_type (id) MATCH SIMPLE, + UNIQUE (fk_azimut, rank) ); diff --git a/data_model/ordinary_data/sign.sql b/data_model/ordinary_data/sign.sql index bf0b7ac9..39a6dda4 100644 --- a/data_model/ordinary_data/sign.sql +++ b/data_model/ordinary_data/sign.sql @@ -2,7 +2,9 @@ CREATE TABLE siro_od.sign ( id uuid PRIMARY KEY default uuid_generate_v1(), + fk_frame uuid not null, rank int default 1, + verso boolean not null default false, fk_sign_type int NOT NULL, fk_official_sign text, fk_parent uuid, --self-reference @@ -14,20 +16,19 @@ CREATE TABLE siro_od.sign case_id text, case_decision text, -- date_repose - fk_frame uuid, fk_coating int, fk_lighting int, destination text, - azimut smallint, comment text, photo text, + CONSTRAINT fkey_od_frame FOREIGN KEY (fk_frame) REFERENCES siro_od.frame (id) MATCH SIMPLE, CONSTRAINT fkey_vl_sign_type FOREIGN KEY (fk_sign_type) REFERENCES siro_vl.sign_type (id) MATCH SIMPLE, CONSTRAINT fkey_vl_official_sign FOREIGN KEY (fk_official_sign) REFERENCES siro_vl.official_sign (id) MATCH SIMPLE, CONSTRAINT fkey_od_sign FOREIGN KEY (fk_parent) REFERENCES siro_od.sign (id) MATCH SIMPLE, CONSTRAINT fkey_od_owner FOREIGN KEY (fk_owner) REFERENCES siro_od.owner (id) MATCH SIMPLE, CONSTRAINT fkey_vl_durability FOREIGN KEY (fk_durability) REFERENCES siro_vl.durability (id) MATCH SIMPLE, - CONSTRAINT fkey_frame FOREIGN KEY (fk_frame) REFERENCES siro_od.frame (id) MATCH SIMPLE, CONSTRAINT fkey_vl_coating FOREIGN KEY (fk_coating) REFERENCES siro_vl.coating (id) MATCH SIMPLE, CONSTRAINT fkey_vl_lighting FOREIGN KEY (fk_lighting) REFERENCES siro_vl.lighting (id) MATCH SIMPLE, - CONSTRAINT fkey_vl_status FOREIGN KEY (fk_status) REFERENCES siro_vl.status (id) MATCH SIMPLE + CONSTRAINT fkey_vl_status FOREIGN KEY (fk_status) REFERENCES siro_vl.status (id) MATCH SIMPLE, + unique(fk_frame, rank, verso) ); \ No newline at end of file diff --git a/data_model/setup.sh b/data_model/setup.sh index 2429e771..1601a6f4 100755 --- a/data_model/setup.sh +++ b/data_model/setup.sh @@ -76,12 +76,14 @@ psql "service=${PGSERVICE}" -v ON_ERROR_STOP=1 -f ${DIR}/value_lists/official_si psql "service=${PGSERVICE}" -v ON_ERROR_STOP=1 -f ${DIR}/ordinary_data/owner.sql psql "service=${PGSERVICE}" -v ON_ERROR_STOP=1 -f ${DIR}/ordinary_data/support.sql +psql "service=${PGSERVICE}" -v ON_ERROR_STOP=1 -f ${DIR}/ordinary_data/azimut.sql psql "service=${PGSERVICE}" -v ON_ERROR_STOP=1 -f ${DIR}/ordinary_data/frame.sql psql "service=${PGSERVICE}" -v ON_ERROR_STOP=1 -f ${DIR}/ordinary_data/sign.sql if [[ $demo_data == True ]]; then echo "*** inserting demo_data" - psql "service=${PGSERVICE}" -v ON_ERROR_STOP=1 -f ${DIR}/demo_data/demo_data.sql + # for now demo data is the test data + psql "service=${PGSERVICE}" -v ON_ERROR_STOP=1 -f ${DIR}/../test/test_data.sql fi ${DIR}/views/create_views.py --pg_service ${PGSERVICE} --srid=${SRID} diff --git a/data_model/views/vw_sign_symbol.py b/data_model/views/vw_sign_symbol.py index ea072497..9210cfdb 100644 --- a/data_model/views/vw_sign_symbol.py +++ b/data_model/views/vw_sign_symbol.py @@ -26,33 +26,51 @@ def vw_sign_symbol(srid: int, pg_service: str = None): view_sql = """ CREATE OR REPLACE VIEW siro_od.vw_sign_symbol AS - WITH ordered_signs AS ( + WITH joined_tables AS ( SELECT sign.id - , az_group.azimut_group + , azimut.azimut , {sign_columns} - , {vl_official_sign_columns} - , ROW_NUMBER () OVER ( - PARTITION BY azimut_group - ) AS final_rank + , sign.rank AS sign_rank + , frame.id AS frame_id + , frame.rank AS frame_rank , support.id AS support_id , support.geometry::geometry(Point,%(SRID)s) AS support_geometry + , {vl_official_sign_columns} FROM siro_od.sign - LEFT JOIN siro_od.frame ON frame.id = sign.fk_frame - LEFT JOIN siro_od.support ON support.id = frame.fk_support - LEFT JOIN siro_vl.official_sign ON official_sign.id = sign.fk_official_sign - LEFT JOIN generate_series(-5,355,10) az_group (azimut_group) - ON sign.azimut >= az_group.azimut_group - AND sign.azimut < az_group.azimut_group + 10 - ORDER BY azimut_group, final_rank - ) - SELECT - ordered_signs.*, - SUM( vl_official_sign_img_height ) OVER rolling_window AS shift - FROM - ordered_signs - WINDOW rolling_window AS ( PARTITION BY support_id, azimut_group ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) - ; + LEFT JOIN siro_od.frame ON frame.id = sign.fk_frame + LEFT JOIN siro_od.azimut ON azimut.id = frame.fk_azimut + LEFT JOIN siro_od.support ON support.id = azimut.fk_support + LEFT JOIN siro_vl.official_sign ON official_sign.id = sign.fk_official_sign + ), + ordered_recto_signs AS ( + SELECT + joined_tables.* + , ROW_NUMBER () OVER ( PARTITION BY support_id, azimut ORDER BY frame_rank, sign_rank ) AS final_rank + FROM joined_tables + WHERE verso IS FALSE + ORDER BY support_id, azimut, final_rank + ), + ordered_shifted_recto_signs AS ( + SELECT + ordered_recto_signs.* + , SUM( vl_official_sign_img_height ) OVER ( PARTITION BY support_id, azimut ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS shift + , NULLIF(FIRST_VALUE(id) OVER (PARTITION BY support_id, azimut, frame_rank ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ), id) AS previous_sign_in_frame + , NULLIF(LAST_VALUE(id) OVER ( PARTITION BY support_id, azimut, frame_rank ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING ), id) AS next_sign_in_frame + , NULLIF(FIRST_VALUE(frame_id) OVER ( PARTITION BY support_id, azimut ROWS BETWEEN 1 PRECEDING AND CURRENT ROW ), frame_id) AS previous_frame + , NULLIF(LAST_VALUE(frame_id) OVER ( PARTITION BY support_id, azimut ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING ), frame_id) AS next_frame + FROM + ordered_recto_signs + ORDER BY + support_id, azimut, final_rank + ) + SELECT * FROM ordered_shifted_recto_signs + UNION + SELECT jt.*, osrs.final_rank, osrs.shift, NULL::uuid AS previous_sign_in_frame, NULL::uuid AS next_sign_in_frame, NULL::uuid AS previous_frame, NULL::uuid AS next_frame + FROM joined_tables jt + LEFT JOIN ordered_shifted_recto_signs osrs ON osrs.support_id = jt.support_id AND osrs.frame_id = jt.frame_id AND jt.sign_rank = osrs.sign_rank + WHERE jt.verso IS TRUE + ; """.format( sign_columns=select_columns( pg_cur=cursor, table_schema='siro_od', table_name='sign', diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/official_sign_images.sh b/test/official_sign_images.sh similarity index 100% rename from tests/official_sign_images.sh rename to test/official_sign_images.sh diff --git a/test/test_data.sql b/test/test_data.sql new file mode 100644 index 00000000..a421811d --- /dev/null +++ b/test/test_data.sql @@ -0,0 +1,67 @@ +-- Insert supports + +INSERT INTO siro_od.support(fk_support_type,fk_support_base_type,fk_status,geometry) VALUES (1,1,1,ST_GeomFromText('POINT(2538388.0 1152589.8)',2056)); +INSERT INTO siro_od.support(id,fk_support_type,fk_support_base_type,fk_status,geometry) VALUES ('00000000-0000-0000-0000-000000000001',1,1,1,ST_GeomFromText('POINT(2537954.42 1152523.14)',2056)); +INSERT INTO siro_od.support(id,fk_support_type,fk_support_base_type,fk_status,geometry) VALUES ('00000000-0000-0000-0000-000000000002',3,2,1,ST_GeomFromText('POINT(2538449.48 1152512.22)',2056)); + +-- Insert azimut +INSERT INTO siro_od.azimut (id, fk_support, azimut) VALUES ('00000000-0000-0000-aaaa-000000000101', '00000000-0000-0000-0000-000000000001', 15); +INSERT INTO siro_od.azimut (id, fk_support, azimut) VALUES ('00000000-0000-0000-aaaa-000000000102', '00000000-0000-0000-0000-000000000001', 175); +INSERT INTO siro_od.azimut (id, fk_support, azimut) VALUES ('00000000-0000-0000-aaaa-000000000103', '00000000-0000-0000-0000-000000000001', 235); +INSERT INTO siro_od.azimut (id, fk_support, azimut) VALUES ('00000000-0000-0000-aaaa-000000000201', '00000000-0000-0000-0000-000000000002', 47); +INSERT INTO siro_od.azimut (id, fk_support, azimut) VALUES ('00000000-0000-0000-aaaa-000000000202', '00000000-0000-0000-0000-000000000002', 165); + +-- Insert frame rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000010101', 1 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000101'); -- support 1 azimut 1 +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000010102', 2 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000101'); -- support 1 azimut 1 +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000010201', 1 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000102'); -- support 1 azimut 2 +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000010202', 2 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000102'); -- support 1 azimut 2 +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000010203', 3 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000102'); -- support 1 azimut 2 +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000010301', 1 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000103'); -- support 1 azimut 3 +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000010302', 2 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000103'); -- support 1 azimut 3 +-- +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000020101', 1 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000201'); -- support 2 azimut 1 +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000020201', 1 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000202'); -- support 2 azimut 2 +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000020202', 2 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000202'); -- support 2 azimut 2 +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000020203', 3 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000202'); -- support 2 azimut 2 +INSERT INTO siro_od.frame (id,rank,fk_frame_type,fk_frame_fixing_type,fk_status,fk_azimut) VALUES ('00000000-0000-0000-ffff-000000020204', 4 , 1 , 1 , 1 ,'00000000-0000-0000-aaaa-000000000202'); -- support 2 azimut 2 + + +-- Insert signs id, S A F R rank,fk_sign_type,fk_official_sign fk_durability fk_status fk_frame +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000001010101', 1 , 1 , '1.01' , 1 , 1 ,'00000000-0000-0000-ffff-000000010101'); -- support 1, azimut 1, frame 1, rank 1 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000001010102', 2 , 1 , '4.52' , 1 , 1 ,'00000000-0000-0000-ffff-000000010101'); -- support 1, azimut 1, frame 1, rank 2 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000001010201', 1 , 1 , '1.03' , 1 , 1 ,'00000000-0000-0000-ffff-000000010102'); -- support 1, azimut 1, frame 2, rank 1 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000001020101', 1 , 1 , '1.14' , 1 , 1 ,'00000000-0000-0000-ffff-000000010201'); -- support 1, azimut 2, frame 1, rank 1 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000001020201', 1 , 1 , '1.25a' , 1 , 1 ,'00000000-0000-0000-ffff-000000010202'); -- support 1, azimut 2, frame 2, rank 1 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000001020301', 1 , 1 , '1.30' , 1 , 1 ,'00000000-0000-0000-ffff-000000010203'); -- support 1, azimut 2, frame 3, rank 1 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000001030101', 1 , 1 , '2.15.1' , 1 , 1 ,'00000000-0000-0000-ffff-000000010301'); -- support 1, azimut 3, frame 1, rank 1 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000001030201', 1 , 1 , '2.16' , 1 , 1 ,'00000000-0000-0000-ffff-000000010302'); -- support 1, azimut 3, frame 2, rank 1 +-- Insert signs id, S A F R rank,fk_sign_type,fk_official_sign fk_durability fk_status fk_frame +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000002010101', 1 , 1 , '1.01' , 1 , 1 ,'00000000-0000-0000-ffff-000000020101'); -- support 2, azimut 1, frame 1, rank 1 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000002020101', 1 , 1 , '4.52' , 1 , 1 ,'00000000-0000-0000-ffff-000000020201'); -- support 2, azimut 2, frame 1, rank 1 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000002020201', 1 , 1 , '1.03' , 1 , 1 ,'00000000-0000-0000-ffff-000000020202'); -- support 2, azimut 2, frame 2, rank 1 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000002020202', 2 , 1 , '1.14' , 1 , 1 ,'00000000-0000-0000-ffff-000000020202'); -- support 2, azimut 2, frame 2, rank 2 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000002020203', 3 , 1 , '1.14' , 1 , 1 ,'00000000-0000-0000-ffff-000000020202'); -- support 2, azimut 2, frame 2, rank 3 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000002020301', 1 , 1 , '1.25a' , 1 , 1 ,'00000000-0000-0000-ffff-000000020203'); -- support 2, azimut 2, frame 3, rank 1 +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame) VALUES ('00000000-0000-0000-eeee-000002020401', 1 , 1 , '1.30' , 1 , 1 ,'00000000-0000-0000-ffff-000000020204'); -- support 2, azimut 2, frame 4, rank 1 +-- Insert verso signs +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame,verso) VALUES ('00000000-0000-0000-eeee-000012020201', 1 , 1 , '1.30' , 1 , 1 ,'00000000-0000-0000-ffff-000000020202', true); -- support 2, azimut 2, frame 2, rank 1 VERSO +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame,verso) VALUES ('00000000-0000-0000-eeee-000012020202', 2 , 1 , '1.30' , 1 , 1 ,'00000000-0000-0000-ffff-000000020202', true); -- support 2, azimut 2, frame 2, rank 2 VERSO +INSERT INTO siro_od.sign (id,rank,fk_sign_type,fk_official_sign,fk_durability,fk_status,fk_frame,verso) VALUES ('00000000-0000-0000-eeee-000012020203', 1 , 1 , '1.30' , 1 , 1 ,'00000000-0000-0000-ffff-000000020203', true); -- support 2, azimut 2, frame 3, rank 1 VERSO + + + + + + + + + + + + + + + + + diff --git a/test/test_view_sign_symbol.py b/test/test_view_sign_symbol.py new file mode 100644 index 00000000..6a75abe5 --- /dev/null +++ b/test/test_view_sign_symbol.py @@ -0,0 +1,47 @@ +import unittest +import os + +import psycopg2 +import psycopg2.extras +import decimal +import copy + +from .utils import DbTestBase + + +class TestViews(unittest.TestCase, DbTestBase): + + @classmethod + def tearDownClass(cls): + cls.conn.rollback() + + @classmethod + def setUpClass(cls): + pgservice=os.environ.get('PGSERVICE') or 'siro_build' + cls.conn = psycopg2.connect("service={service}".format(service=pgservice)) + + def test_view(self): + data = [ + {'id': '00000000-0000-0000-eeee-000001010101', 'row': {'azimut': 15, 'final_rank': 1, 'previous_sign_in_frame': None, 'next_sign_in_frame': '00000000-0000-0000-eeee-000001010102', 'previous_frame': None, 'next_frame': None}}, + {'id': '00000000-0000-0000-eeee-000001010102', 'row': {'azimut': 15, 'final_rank': 2, 'previous_sign_in_frame': '00000000-0000-0000-eeee-000001010101', 'next_sign_in_frame': None, 'previous_frame': None, 'next_frame': '00000000-0000-0000-ffff-000000010102'}}, + {'id': '00000000-0000-0000-eeee-000001010201', 'row': {'azimut': 15, 'final_rank': 3, 'previous_sign_in_frame': None, 'next_sign_in_frame': None, 'previous_frame': '00000000-0000-0000-ffff-000000010101', 'next_frame': None}}, + {'id': '00000000-0000-0000-eeee-000001020101', 'row': {'azimut': 175, 'final_rank': 1, 'previous_sign_in_frame': None, 'next_sign_in_frame': None, 'previous_frame': None, 'next_frame': '00000000-0000-0000-ffff-000000010202'}}, + {'id': '00000000-0000-0000-eeee-000001020201', 'row': {'azimut': 175, 'final_rank': 2, 'previous_sign_in_frame': None, 'next_sign_in_frame': None, 'previous_frame': '00000000-0000-0000-ffff-000000010201', 'next_frame': '00000000-0000-0000-ffff-000000010203'}}, + {'id': '00000000-0000-0000-eeee-000001020301', 'row': {'azimut': 175, 'final_rank': 3, 'previous_sign_in_frame': None, 'next_sign_in_frame': None, 'previous_frame': '00000000-0000-0000-ffff-000000010202', 'next_frame': None}}, + {'id': '00000000-0000-0000-eeee-000001030101', 'row': {'azimut': 235, 'final_rank': 1, 'previous_sign_in_frame': None, 'next_sign_in_frame': None, 'previous_frame': None, 'next_frame': '00000000-0000-0000-ffff-000000010302'}}, + {'id': '00000000-0000-0000-eeee-000001030201', 'row': {'azimut': 235, 'final_rank': 2, 'previous_sign_in_frame': None, 'next_sign_in_frame': None, 'previous_frame': '00000000-0000-0000-ffff-000000010301', 'next_frame': None}}, + + {'id': '00000000-0000-0000-eeee-000002010101', 'row': {'azimut': 47, 'final_rank': 1, 'previous_sign_in_frame': None, 'next_sign_in_frame': None, 'previous_frame': None, 'next_frame': None}}, + {'id': '00000000-0000-0000-eeee-000002020101', 'row': {'azimut': 165, 'final_rank': 1, 'previous_sign_in_frame': None, 'next_sign_in_frame': None, 'previous_frame': None, 'next_frame': '00000000-0000-0000-ffff-000000020202'}}, + {'id': '00000000-0000-0000-eeee-000002020201', 'row': {'azimut': 165, 'final_rank': 2, 'previous_sign_in_frame': None, 'next_sign_in_frame': '00000000-0000-0000-eeee-000002020202', 'previous_frame': '00000000-0000-0000-ffff-000000020201', 'next_frame': None}}, + {'id': '00000000-0000-0000-eeee-000002020202', 'row': {'azimut': 165, 'final_rank': 3, 'previous_sign_in_frame': '00000000-0000-0000-eeee-000002020201', 'next_sign_in_frame': '00000000-0000-0000-eeee-000002020203', 'previous_frame': None, 'next_frame': None}}, + {'id': '00000000-0000-0000-eeee-000002020203', 'row': {'azimut': 165, 'final_rank': 4, 'previous_sign_in_frame': '00000000-0000-0000-eeee-000002020202', 'next_sign_in_frame': None, 'previous_frame': None, 'next_frame': '00000000-0000-0000-ffff-000000020203'}}, + {'id': '00000000-0000-0000-eeee-000002020301', 'row': {'azimut': 165, 'final_rank': 5, 'previous_sign_in_frame': None, 'next_sign_in_frame': None, 'previous_frame': '00000000-0000-0000-ffff-000000020202', 'next_frame': '00000000-0000-0000-ffff-000000020204'}}, + {'id': '00000000-0000-0000-eeee-000002020401', 'row': {'azimut': 165, 'final_rank': 6, 'previous_sign_in_frame': None, 'next_sign_in_frame': None, 'previous_frame': '00000000-0000-0000-ffff-000000020203', 'next_frame': None}}, + ] + for row in data: + self.check(row['row'], 'vw_sign_symbol', row['id']) + + +if __name__ == '__main__': + unittest.main() diff --git a/test/utils.py b/test/utils.py new file mode 100644 index 00000000..64ba6c15 --- /dev/null +++ b/test/utils.py @@ -0,0 +1,129 @@ +import unittest + +import psycopg2 +import psycopg2.extras + + +class DbTestBase: + + def assert_count(self, table, schema, expected): + cur = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor) + cur.execute("SELECT COUNT(*) FROM {schema}.{table}".format(table=table, schema=schema)) + count = cur.fetchone()[0] + assert count == expected, "Relation {}.{} : expected {} rows, got {} rows".format(schema, table, expected, count) + + def select(self, table, id, schema='siro_od'): + cur = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor) + cur.execute("SELECT * FROM {schema}.{table} WHERE id=%(id)s" + .format(table=table, schema=schema), + {'id': id}) + return cur.fetchone() + + def execute(self, sql: str, params=[]): + cur = self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor) + cur.execute("SELECT {}".format(sql), params) + return cur.fetchone()[0] + + def cursor(self): + return self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor) + + def insert(self, table, row, schema='siro_od'): + cur = self.conn.cursor() + cols = ', '.join(row.keys()) + values = ', '.join(["%({key})s".format(key=key) for key in row.keys()]) + cur.execute("INSERT INTO {schema}.{table} ({cols}) VALUES ({values}) RETURNING id" + .format(table=table, schema=schema, cols=cols, values=values), + row) + return cur.fetchone()[0] + + def update(self, table, row, id, schema='siro_od'): + cur = self.conn.cursor() + cols = ','.join(['{key}=%({key})s'.format(key=key) for key in row.keys()]) + row['id'] = id + cur.execute("UPDATE {schema}.{table} SET {cols} WHERE id=%(id)s" + .format(table=table, schema=schema, cols=cols), + row) + + def delete(self, table, id, schema='siro_od'): + cur = self.conn.cursor() + cur.execute("DELETE FROM {schema}.{table} WHERE id=%s" + .format(table=table, schema=schema), [id]) + + def insert_check(self, table, row, expected_row=None, schema='siro_od'): + id = self.insert(table, row, schema) + result = self.select(table, id, schema) + + assert result, id + + if expected_row: + row = expected_row + + self.check_result(row, result, table, 'insert', schema) + + return id + + def update_check(self, table, row, id, schema='siro_od'): + self.update(table, row, id, schema) + result = self.select(table, id, schema) + self.check_result(row, result, table, 'update', schema) + + def check(self, expected, table, id, schema='siro_od'): + result = self.select(table, id, schema) + self.check_result(expected, result, table, 'update', schema) + + def check_result(self, expected, result, table, test_name, schema='siro_od'): + # TODO: don't convert to unicode, type inference for smallint is + # currently broken, that's the reason at the moment. + self.assertTrue(result, "No result set received.") + + for key, value in expected.items(): + self.assertEqual(str(result[key]), str(value), """ + ======================================================== + + Data: {expected} + + ======================================================== + + Failed {test_name} test on + Table: "{table}" + Schema: "{schema}" + Field: "{key}" + expected: {expected_value} ({expected_type}) + result: {result_value} ({result_type}) + + ======================================================== + """.format( + expected = repr(expected), + test_name = test_name, + table = table, + schema = schema, + key = key, + expected_value = value, + result_value = result[key], + expected_type = type(value), + result_type = type(result[key]) + )) + + def make_line(self, x1, y1, z1, x2, y2, z2, srid=2056): + """ + Helper to make 3D line geometries + """ + return self.execute('ST_ForceCurve(ST_SetSrid(ST_MakeLine(ST_MakePoint(%s, %s, %s), ST_MakePoint(%s, %s, %s)), %s))', [x1, y1, z1, x2, y2, z2, srid]) + + def make_line_2d(self, x1, y1, x2, y2, srid=2056): + """ + Helper to make 2D line geometries + """ + return self.execute('ST_ForceCurve(ST_SetSrid(ST_MakeLine(ST_MakePoint(%s, %s), ST_MakePoint(%s, %s)), %s))', [x1, y1, x2, y2, srid]) + + def make_point(self, x, y, z, srid=2056): + """ + Helper to make 3D point geometries + """ + return self.execute('ST_SetSrid(ST_MakePoint(%s, %s, %s), %s)', [x, y, z, srid]) + + def make_point_2d(self, x, y, z=None, srid=2056): + """ + Helper to make 2D point geometries + """ + return self.execute('ST_SetSrid(ST_MakePoint(%s, %s), %s)', [x, y, srid])