|
| 1 | ++++ |
| 2 | +title = "Schema Design - Part 1: Trigger-based SQL" |
| 3 | +slug = "schema-design-sql" |
| 4 | +date = "2020-01-02T00:00:00-00:00" |
| 5 | +tags = ["schema-design", "sql"] |
| 6 | +showpagemeta = true |
| 7 | ++++ |
| 8 | + |
| 9 | +TODO |
| 10 | + |
| 11 | +## Deposition |
| 12 | + |
| 13 | +TODO |
| 14 | + |
| 15 | +[earlier post](https://eric-fritz.com/articles/deposition/) |
| 16 | + |
| 17 | +[earlier post](https://eric-fritz.com/articles/easy-peasy-sql-audit-tables/) |
| 18 | + |
| 19 | + |
| 20 | +{{< lightbox src="/images/deposition-schema.png" anchor="deposition-schema" >}} |
| 21 | + |
| 22 | +TODO - After insert, update, delete on builds: |
| 23 | + |
| 24 | +```sql |
| 25 | +CREATE FUNCTION update_product( |
| 26 | + target_team_id integer, target_name text |
| 27 | +) RETURNS void LANGUAGE plpgsql AS $$ BEGIN |
| 28 | + UPDATE products p |
| 29 | + SET |
| 30 | + active = ep.active, |
| 31 | + deployed = ep.deployed, |
| 32 | + flagged = ep.flagged, |
| 33 | + active_flagged = ep.active_flagged, |
| 34 | + deploy_flagged = ep.deploy_flagged |
| 35 | + FROM expanded_products ep |
| 36 | + WHERE |
| 37 | + ep.team_id = target_team_id AND p.team_id = target_team_id AND |
| 38 | + ep.name = target_name AND p.name = target_name; |
| 39 | +END $$; |
| 40 | + |
| 41 | +CREATE VIEW expanded_products AS |
| 42 | + SELECT |
| 43 | + p.team_id, |
| 44 | + p.name, |
| 45 | + COALESCE(bool_or(b.active), false) AS active, |
| 46 | + COALESCE(bool_or(b.deployed), false) AS deployed, |
| 47 | + COALESCE(bool_or(b.flagged), false) AS flagged, |
| 48 | + COALESCE(bool_or((b.active AND b.flagged)), false) AS active_flagged, |
| 49 | + COALESCE(bool_or((b.deployed AND b.flagged)), false) AS deploy_flagged |
| 50 | + FROM products p |
| 51 | + LEFT JOIN builds b ON ... |
| 52 | + GROUP BY p.team_id, p.name; |
| 53 | +``` |
| 54 | + |
| 55 | +TODO / After insert on builds, insert/delte on build deployments |
| 56 | + |
| 57 | +```sql |
| 58 | +CREATE FUNCTION set_active_build( |
| 59 | + target_team_id integer, target_name text |
| 60 | +) RETURNS void LANGUAGE plpgsql AS $$ BEGIN |
| 61 | + UPDATE builds b |
| 62 | + SET active = EXISTS ( |
| 63 | + SELECT 1 FROM build_deployments d WHERE |
| 64 | + d.build_product_name = b.product_name AND |
| 65 | + d.build_version = b.version AND |
| 66 | + d.build_token = b.build_token |
| 67 | + ) OR EXISTS ( |
| 68 | + SELECT 1 FROM active_builds ab WHERE |
| 69 | + b.product_name = ab.product_name AND |
| 70 | + b.version = ab.version AND |
| 71 | + b.build_token = ab.build_token |
| 72 | + ) |
| 73 | + WHERE |
| 74 | + b.product_team_id = target_team_id AND |
| 75 | + b.product_name = target_name; |
| 76 | +END $$; |
| 77 | + |
| 78 | +CREATE VIEW active_builds AS |
| 79 | + SELECT b.* FROM products p JOIN builds b |
| 80 | + ON ... |
| 81 | + AND NOT EXISTS ( |
| 82 | + SELECT 1 FROM builds cmp WHERE |
| 83 | + cmp.product_team_id = p.team_id AND cmp.product_name = p.name AND |
| 84 | + cmp.build_datetime > b.build_datetime |
| 85 | + ) |
| 86 | + ORDER BY b.build_datetime DESC; |
| 87 | +``` |
| 88 | + |
| 89 | +TODO / After insert, delete on build_deployments |
| 90 | + |
| 91 | +```sql |
| 92 | +CREATE FUNCTION update_build_deployment( |
| 93 | + target_team_id integer, target_name text, |
| 94 | + target_version text, target_build_token text |
| 95 | +) RETURNS void LANGUAGE plpgsql AS $$ BEGIN |
| 96 | + UPDATE builds b |
| 97 | + SET deployed = bd.deployed |
| 98 | + FROM expanded_build_deployments bd |
| 99 | + WHERE |
| 100 | + bd.product_team_id = target_team_id AND b.product_team_id = target_team_id AND |
| 101 | + bd.product_name = target_name AND b.product_name = target_name AND |
| 102 | + bd.version = target_version AND b.version = target_version AND |
| 103 | + bd.build_token = target_build_token AND b.build_token = target_build_token; |
| 104 | +END $$; |
| 105 | + |
| 106 | +CREATE VIEW expanded_build_deployments AS |
| 107 | + SELECT |
| 108 | + b.product_team_id, |
| 109 | + b.product_name, |
| 110 | + b.version, |
| 111 | + b.build_token, |
| 112 | + (count(bd.deployment_token) > 0) AS deployed |
| 113 | + FROM builds b |
| 114 | + LEFT JOIN build_deployments bd ON ... |
| 115 | + GROUP BY b.product_team_id, b.product_name, b.version, b.build_token; |
| 116 | +``` |
| 117 | + |
| 118 | +TODO / After insert/update/delete on dependency_versions and dependency_version_flags |
| 119 | + |
| 120 | +```sql |
| 121 | +CREATE FUNCTION update_dependencies( |
| 122 | + target_source text, target_name text |
| 123 | +) RETURNS void LANGUAGE plpgsql AS $$ BEGIN |
| 124 | + UPDATE dependencies d |
| 125 | + SET flagged = ed.flagged |
| 126 | + FROM expanded_dependencies ed |
| 127 | + WHERE |
| 128 | + ed.source = target_source AND d.source = target_source AND |
| 129 | + ed.name = target_name AND d.name = target_name; |
| 130 | +END $$; |
| 131 | + |
| 132 | +CREATE VIEW expanded_dependencies AS |
| 133 | + SELECT |
| 134 | + d.source, |
| 135 | + d.name, |
| 136 | + EXISTS ( |
| 137 | + SELECT 1 FROM dependency_version_flags dvf WHERE |
| 138 | + d.source = dvf.dependency_version_source AND |
| 139 | + d.name = dvf.dependency_version_name |
| 140 | + ) AS flagged |
| 141 | + FROM dependencies d; |
| 142 | +``` |
| 143 | + |
| 144 | +TODO / After insert/update/delete on dependency_version_flags |
| 145 | + |
| 146 | +```sql |
| 147 | +CREATE FUNCTION update_build( |
| 148 | + target_team_id integer, target_name text, |
| 149 | + target_version text, target_build_token text |
| 150 | +) RETURNS void LANGUAGE plpgsql AS $$ DECLARE items RECORD; BEGIN |
| 151 | + UPDATE builds b |
| 152 | + SET flagged = eb.flagged |
| 153 | + FROM expanded_builds eb |
| 154 | + WHERE |
| 155 | + eb.product_team_id = target_team_id AND b.product_team_id = target_team_id AND |
| 156 | + eb.product_name = target_name AND b.product_name = target_name AND |
| 157 | + eb.version = target_version AND b.version = target_version AND |
| 158 | + eb.build_token = target_build_token AND b.build_token = target_build_token; |
| 159 | +END $$; |
| 160 | + |
| 161 | +CREATE VIEW expanded_builds AS |
| 162 | + SELECT |
| 163 | + b.product_team_id, |
| 164 | + b.product_name, |
| 165 | + b.version, |
| 166 | + b.build_token, |
| 167 | + (count(DISTINCT dvf.dependency_version_flag_id) > 0) AS flagged |
| 168 | + FROM |
| 169 | + ( |
| 170 | + builds b |
| 171 | + LEFT JOIN build_dependency_versions bdv ON ... |
| 172 | + LEFT JOIN dependency_versions v ON ... |
| 173 | + LEFT JOIN dependency_version_flags dvf ON |
| 174 | + ... AND |
| 175 | + (dvf.apply_globally OR dvf.team_id = b.product_team_id) |
| 176 | + ) |
| 177 | + GROUP BY b.product_team_id, b.product_name, b.version, b.build_token; |
| 178 | +``` |
| 179 | + |
| 180 | +TODO |
0 commit comments