Skip to content

Commit f8f5a79

Browse files
perrymanmdmperryman2
andauthored
Add "approved" bit to quality codes (#194)
* update python script that generates sql build scripts - update cwms_data_quality table to have additional column - update sqlldr control file to add approved column - update sqlldr data file to add extra quality codes * add av_data_q_approval view * update av_data_quality view to have additional column * update schema build scripts include av_data_q_approval view * update/add quality routines cwms_ts package * add test_quality_codes test to test_cwms_ts package Co-authored-by: mperryman2 <MPerryman@geiconsultants.com>
1 parent 5524e83 commit f8f5a79

8 files changed

Lines changed: 302 additions & 57 deletions

File tree

schema/src/buildSqlScripts.py

Lines changed: 97 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ def getRandomFilename() :
117117
{"ID" : "qReplCause", "TABLE" : "CWMS_DATA_Q_REPL_CAUSE", "SCHEMA" : "CWMS", "USERACCESS" : True},
118118
{"ID" : "qReplMethod", "TABLE" : "CWMS_DATA_Q_REPL_METHOD", "SCHEMA" : "CWMS", "USERACCESS" : True},
119119
{"ID" : "qTestFailed", "TABLE" : "CWMS_DATA_Q_TEST_FAILED", "SCHEMA" : "CWMS", "USERACCESS" : True},
120+
{"ID" : "qApproval", "TABLE" : "CWMS_DATA_Q_APPROVAL", "SCHEMA" : "CWMS", "USERACCESS" : True},
120121
{"ID" : "qProtection", "TABLE" : "CWMS_DATA_Q_PROTECTION", "SCHEMA" : "CWMS", "USERACCESS" : True},
121122
{"ID" : "quality", "TABLE" : "CWMS_DATA_QUALITY", "SCHEMA" : "CWMS", "USERACCESS" : True},
122123
{"ID" : "ratingMethod", "TABLE" : "CWMS_RATING_METHOD", "SCHEMA" : "CWMS", "USERACCESS" : True},
@@ -4514,7 +4515,7 @@ def getRandomFilename() :
45144515
45154516
1. Unless the Screened bit is set, no other bits can be set.
45164517
4517-
2. Unused bits (22, 24, 27-31, 32+) must be reset (zero).
4518+
2. Unused bits (22, 24, 27-30, 32+) must be reset (zero).
45184519
45194520
3. The Okay, Missing, Questioned and Rejected bits are mutually
45204521
exclusive.
@@ -4531,20 +4532,23 @@ def getRandomFilename() :
45314532
7. The Test Failed bits are not mutually exclusive (multiple tests can be
45324533
marked as failed).
45334534
4535+
8. The Approved bit may not be set unless the Protected bit is also set
4536+
45344537
Bit Mappings :
45354538
45364539
3 2 1
45374540
2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1
45384541
4539-
P - - - - - T T T T T T T T T T T M M M M C C C D R R V V V V S
4540-
| <---------+---------> <--+--> <-+-> | <+> <--+--> |
4541-
| | | | | | | +------Screened T/F
4542-
| | | | | | +-----------Validity Flags
4543-
| | | | | +--------------Value Range Integer
4544-
| | | | +-------------------Different T/F
4545-
| | | +---------------Replacement Cause Integer
4546-
| | +---------------------Replacement Method Integer
4547-
| +-------------------------------------------Test Failed Flags
4542+
P A - - - - T T T T T T T T T T T M M M M C C C D R R V V V V S
4543+
| | <---------+---------> <--+--> <-+-> | <+> <--+--> |
4544+
| | | | | | | | +------Screened T/F
4545+
| | | | | | | +-----------Validity Flags
4546+
| | | | | | +--------------Value Range Integer
4547+
| | | | | +-------------------Different T/F
4548+
| | | | +---------------Replacement Cause Integer
4549+
| | | +---------------------Replacement Method Integer
4550+
| | +-------------------------------------------Test Failed Flags
4551+
| +------------------------------------------------------------------Approved T/F
45484552
+-------------------------------------------------------------------Protected T/F
45494553
45504554
'''
@@ -4628,6 +4632,12 @@ def getRandomFilename() :
46284632
desc = "The value failed %d tests" % len(items)
46294633
q_test_failed["values"].append((value, id, desc))
46304634

4635+
q_approval = {
4636+
"shift" : 30,
4637+
"values" : [
4638+
(0, "NOT_APPROVED", "The value has not be manually approved"),
4639+
(1, "APPROVED", "The value has been manually approved" )]}
4640+
46314641
q_protection = {
46324642
"shift" : 31,
46334643
"values" : [
@@ -8357,6 +8367,53 @@ def main() :
83578367
qTestFailedLoadTemplate += "INSERT INTO @TABLE VALUES('%s', '%s');\n" % (id, description)
83588368
qTestFailedLoadTemplate += "COMMIT;\n"
83598369

8370+
sys.stderr.write("Building qProtectionCreationTemplate\n")
8371+
global qApprovalCreationTemplate
8372+
qApprovalCreationTemplate = \
8373+
'''
8374+
-- ## TABLE ###############################################
8375+
-- ## @TABLE
8376+
-- ##
8377+
CREATE TABLE @TABLE
8378+
(
8379+
APPROVAL_ID VARCHAR2(16) NOT NULL,
8380+
DESCRIPTION VARCHAR2(80),
8381+
CONSTRAINT @TABLE_PK PRIMARY KEY (APPROVAL_ID)
8382+
)
8383+
PCTFREE 10
8384+
PCTUSED 40
8385+
INITRANS 1
8386+
MAXTRANS 255
8387+
TABLESPACE @DATASPACE
8388+
STORAGE
8389+
(
8390+
INITIAL 10K
8391+
NEXT 10K
8392+
MINEXTENTS 1
8393+
MAXEXTENTS 200
8394+
PCTINCREASE 25
8395+
FREELISTS 1
8396+
FREELIST GROUPS 1
8397+
BUFFER_POOL DEFAULT
8398+
);
8399+
8400+
8401+
---------------------------
8402+
-- @TABLE comments --
8403+
--
8404+
COMMENT ON TABLE @TABLE IS 'Contains valid values for the approval component of CWMS data quality flags';
8405+
COMMENT ON COLUMN @TABLE.APPROVAL_ID IS 'Text identifier of approval component and primary key';
8406+
COMMENT ON COLUMN @TABLE.DESCRIPTION IS 'Text description of approval component';
8407+
8408+
COMMIT;
8409+
'''
8410+
sys.stderr.write("Building qApprovalLoadTemplate\n")
8411+
global qApprovalLoadTemplate
8412+
qApprovalLoadTemplate = ''
8413+
for code, id, description in q_approval["values"] :
8414+
qApprovalLoadTemplate += "INSERT INTO @TABLE VALUES('%s', '%s');\n" % (id, description)
8415+
qApprovalLoadTemplate += "COMMIT;\n"
8416+
83608417
sys.stderr.write("Building qProtectionCreationTemplate\n")
83618418
global qProtectionCreationTemplate
83628419
qProtectionCreationTemplate = \
@@ -8422,6 +8479,7 @@ def main() :
84228479
REPL_METHOD_ID VARCHAR2(16) NOT NULL,
84238480
TEST_FAILED_ID VARCHAR2(125) NOT NULL,
84248481
PROTECTION_ID VARCHAR2(16) NOT NULL,
8482+
APPROVAL_ID VARCHAR2(16) NOT NULL,
84258483
CONSTRAINT @TABLE_PK PRIMARY KEY (QUALITY_CODE)
84268484
)
84278485
PCTFREE 10
@@ -8452,6 +8510,7 @@ def main() :
84528510
ALTER TABLE @TABLE ADD CONSTRAINT @TABLE_FK6 FOREIGN KEY (REPL_CAUSE_ID ) REFERENCES @qReplCauseTableName (REPL_CAUSE_ID );
84538511
ALTER TABLE @TABLE ADD CONSTRAINT @TABLE_FK7 FOREIGN KEY (REPL_METHOD_ID) REFERENCES @qReplMethodTableName (REPL_METHOD_ID);
84548512
ALTER TABLE @TABLE ADD CONSTRAINT @TABLE_FK8 FOREIGN KEY (TEST_FAILED_ID) REFERENCES @qTestFailedTableName (TEST_FAILED_ID);
8513+
ALTER TABLE @TABLE ADD CONSTRAINT @TABLE_FK0 FOREIGN KEY (APPROVAL_ID ) REFERENCES @qApprovalTableName (APPROVAL_ID );
84558514
84568515
---------------------------
84578516
-- @TABLE comments --
@@ -8466,6 +8525,7 @@ def main() :
84668525
COMMENT ON COLUMN @TABLE.REPL_METHOD_ID IS 'Foreign key referencing @qReplMethodTableName table by its primary key';
84678526
COMMENT ON COLUMN @TABLE.TEST_FAILED_ID IS 'Foreign key referencing @qTestFailedTableName table by its primary key';
84688527
COMMENT ON COLUMN @TABLE.PROTECTION_ID IS 'Foreign key referencing @qProtectionTableName table by its primary key';
8528+
COMMENT ON COLUMN @TABLE.APPROVAL_ID IS 'Foreign key referencing @qApprovalTableName table by its primary key';
84698529
COMMIT;
84708530
'''
84718531
sys.stderr.write("Building qualityLoadFile\n")
@@ -8475,11 +8535,11 @@ def main() :
84758535
infile *
84768536
into table cwms_data_quality
84778537
fields terminated by ","
8478-
(QUALITY_CODE,SCREENED_ID,VALIDITY_ID,RANGE_ID,CHANGED_ID,REPL_CAUSE_ID,REPL_METHOD_ID,TEST_FAILED_ID,PROTECTION_ID)
8538+
(QUALITY_CODE,SCREENED_ID,VALIDITY_ID,RANGE_ID,CHANGED_ID,REPL_CAUSE_ID,REPL_METHOD_ID,TEST_FAILED_ID,PROTECTION_ID,APPROVAL_ID)
84798539
begindata
84808540
''')
84818541

8482-
qualityLoadFile.write("%lu,%s,%s,%s,%s,%s,%s,%s,%s\n" % (
8542+
qualityLoadFile.write("%lu,%s,%s,%s,%s,%s,%s,%s,%s,%s\n" % (
84838543
0, # unsigned value
84848544
q_screened["values"][0][1], # screened code
84858545
q_validity["values"][0][1], # validity code
@@ -8488,7 +8548,8 @@ def main() :
84888548
q_replacement_cause["values"][0][1], # replacement cause code
84898549
q_replacement_method["values"][0][1], # replacement method code
84908550
q_test_failed["values"][0][1], # test failed code
8491-
q_protection["values"][0][1])) # protection code
8551+
q_protection["values"][0][1], # protection code
8552+
q_approval["values"][0][1])) # approval code
84928553

84938554
for v in range(len(q_validity["values"])) :
84948555
for r in range(len(q_value_range["values"])) :
@@ -8499,25 +8560,29 @@ def main() :
84998560
if (d > 0) != (m > 0) : continue
85008561
for t in range(len(q_test_failed["values"])) :
85018562
for p in range(len(q_protection["values"])) :
8502-
value = 0 \
8503-
| (q_screened["values"][1][0] << q_screened["shift"]) \
8504-
| (q_validity["values"][v][0] << q_validity["shift"]) \
8505-
| (q_value_range["values"][r][0] << q_value_range["shift"]) \
8506-
| (q_different["values"][d][0] << q_different["shift"]) \
8507-
| (q_replacement_cause["values"][c][0] << q_replacement_cause["shift"]) \
8508-
| (q_replacement_method["values"][m][0] << q_replacement_method["shift"]) \
8509-
| (q_test_failed["values"][t][0] << q_test_failed["shift"]) \
8510-
| (q_protection["values"][p][0] << q_protection["shift"])
8511-
qualityLoadFile.write("%lu,%s,%s,%s,%s,%s,%s,%s,%s\n" % (
8512-
value, # unsigned value
8513-
q_screened["values"][1][1], # screened code
8514-
q_validity["values"][v][1], # validity code
8515-
q_value_range["values"][r][1], # range code
8516-
q_different["values"][d][1], # changed code
8517-
q_replacement_cause["values"][c][1], # replacement cause code
8518-
q_replacement_method["values"][m][1], # replacement method code
8519-
q_test_failed["values"][t][1], # test failed code
8520-
q_protection["values"][p][1])) # protection code
8563+
for a in range(len(q_approval["values"])) :
8564+
if p == 0 and a == 1 : continue
8565+
value = 0 \
8566+
| (q_screened["values"][1][0] << q_screened["shift"]) \
8567+
| (q_validity["values"][v][0] << q_validity["shift"]) \
8568+
| (q_value_range["values"][r][0] << q_value_range["shift"]) \
8569+
| (q_different["values"][d][0] << q_different["shift"]) \
8570+
| (q_replacement_cause["values"][c][0] << q_replacement_cause["shift"]) \
8571+
| (q_replacement_method["values"][m][0] << q_replacement_method["shift"]) \
8572+
| (q_test_failed["values"][t][0] << q_test_failed["shift"]) \
8573+
| (q_protection["values"][p][0] << q_protection["shift"]) \
8574+
| (q_approval["values"][a][0] << q_approval["shift"])
8575+
qualityLoadFile.write("%lu,%s,%s,%s,%s,%s,%s,%s,%s,%s\n" % (
8576+
value, # unsigned value
8577+
q_screened["values"][1][1], # screened code
8578+
q_validity["values"][v][1], # validity code
8579+
q_value_range["values"][r][1], # range code
8580+
q_different["values"][d][1], # changed code
8581+
q_replacement_cause["values"][c][1], # replacement cause code
8582+
q_replacement_method["values"][m][1], # replacement method code
8583+
q_test_failed["values"][t][1], # test failed code
8584+
q_protection["values"][p][1], # protection code
8585+
q_approval["values"][a][1])) # approval code
85218586

85228587
qualityLoadFile.close()
85238588

schema/src/cwms/at_schema_av.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ END;
153153
@@cwms/views/av_cwms_ts_id_dummy
154154
@@cwms/views/av_cwms_ts_id2
155155
@@cwms/views/av_data_q_changed
156+
@@cwms/views/av_data_q_approval
156157
@@cwms/views/av_data_q_protection
157158
@@cwms/views/av_data_q_range
158159
@@cwms/views/av_data_q_repl_cause

schema/src/cwms/cwms_schema_pkg.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ view_names constant object_tab_t := object_tab_t(
274274
'AV_DATAEXCHANGE_JOB',
275275
'AV_DATA_QUALITY',
276276
'AV_DATA_Q_CHANGED',
277+
'AV_DATA_Q_APPROVAL',
277278
'AV_DATA_Q_PROTECTION',
278279
'AV_DATA_Q_RANGE',
279280
'AV_DATA_Q_REPL_CAUSE',

schema/src/cwms/cwms_ts_pkg.sql

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3551,6 +3551,66 @@ AS
35513551
FUNCTION quality_is_protected_text (p_value IN ztsv_type)
35523552
return varchar2;
35533553

3554+
/**
3555+
* Retrieves whether a quality code is marked as approved
3556+
*
3557+
* @param p_quality_code The quality code
3558+
*
3559+
* @return Whether the quality code is marked as approved
3560+
*/
3561+
FUNCTION quality_is_approved (p_quality_code IN NUMBER)
3562+
RETURN BOOLEAN;
3563+
3564+
/**
3565+
* Retrieves whether the quality code of a time series value is marked as approved
3566+
*
3567+
* @param p_value The time series value
3568+
*
3569+
* @return Whether the quality code is marked as approved
3570+
*/
3571+
FUNCTION quality_is_approved (p_value IN tsv_type)
3572+
RETURN BOOLEAN;
3573+
3574+
/**
3575+
* Retrieves whether the quality code of a time series value is marked as approved
3576+
*
3577+
* @param p_value The time series value
3578+
*
3579+
* @return Whether the quality code is marked as approved
3580+
*/
3581+
FUNCTION quality_is_approved (p_value IN ztsv_type)
3582+
RETURN BOOLEAN;
3583+
3584+
/**
3585+
* Retrieves whether a quality code is marked as approved
3586+
*
3587+
* @param p_quality_code The quality code
3588+
*
3589+
* @return Whether the quality code is marked as approved as text ('T'/'F')
3590+
*/
3591+
FUNCTION quality_is_approved_text (p_quality_code IN NUMBER)
3592+
RETURN VARCHAR2;
3593+
3594+
/**
3595+
* Retrieves whether the quality code of a time series value is marked as approved
3596+
*
3597+
* @param p_value The time series value
3598+
*
3599+
* @return Whether the quality code is marked as approved as text ('T'/'F')
3600+
*/
3601+
FUNCTION quality_is_approved_text (p_value IN tsv_type)
3602+
RETURN VARCHAR2;
3603+
3604+
/**
3605+
* Retrieves whether the quality code of a time series value is marked as approved
3606+
*
3607+
* @param p_value The time series value
3608+
*
3609+
* @return Whether the quality code is marked as approved as text ('T'/'F')
3610+
*/
3611+
FUNCTION quality_is_approved_text (p_value IN ztsv_type)
3612+
return varchar2;
3613+
35543614
/**
35553615
* Retrieves a text description for a quality code
35563616
*

0 commit comments

Comments
 (0)