-- Create data sources tableCREATETABLEdata_sources(idSERIALPRIMARYKEY,source_nameVARCHAR(100)UNIQUENOTNULL,source_typeVARCHAR(50)NOTNULL,connection_configJSONBNOTNULL,extraction_queryTEXT,is_activeBOOLEANDEFAULTTRUE,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP,updated_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Create function to register data sourceCREATEORREPLACEFUNCTIONregister_data_source(p_source_nameVARCHAR(100),p_source_typeVARCHAR(50),p_connection_configJSONB,p_extraction_queryTEXTDEFAULTNULL)RETURNSVOIDAS$$BEGININSERTINTOdata_sources(source_name,source_type,connection_config,extraction_query)VALUES(p_source_name,p_source_type,p_connection_config,p_extraction_query)ONCONFLICT(source_name)DOUPDATESETsource_type=EXCLUDED.source_type,connection_config=EXCLUDED.connection_config,extraction_query=EXCLUDED.extraction_query,updated_at=CURRENT_TIMESTAMP;END;$$LANGUAGEplpgsql;-- Create function to extract dataCREATEORREPLACEFUNCTIONextract_data(p_source_nameVARCHAR(100),p_batch_sizeINTEGERDEFAULT1000,p_offsetINTEGERDEFAULT0)RETURNSTABLE(row_dataJSONB,row_numberBIGINT)AS$$DECLAREsource_recordRECORD;extraction_sqlTEXT;BEGIN-- Get source configurationSELECT*INTOsource_recordFROMdata_sourcesWHEREsource_name=p_source_nameANDis_active=TRUE;IFsource_recordISNULLTHENRAISEEXCEPTION'Data source % not found or inactive',p_source_name;ENDIF;-- Build extraction queryIFsource_record.extraction_queryISNOTNULLTHENextraction_sql:=source_record.extraction_query;ELSEextraction_sql:=format('SELECT * FROM %I LIMIT %s OFFSET %s',source_record.source_name,p_batch_size,p_offset);ENDIF;-- Execute extractionRETURNQUERYEXECUTEextraction_sql;END;$$LANGUAGEplpgsql;
-- Create transformation rules tableCREATETABLEtransformation_rules(idSERIALPRIMARYKEY,rule_nameVARCHAR(100)UNIQUENOTNULL,source_tableVARCHAR(100)NOTNULL,target_tableVARCHAR(100)NOTNULL,transformation_logicJSONBNOTNULL,validation_rulesJSONBDEFAULT'{}',is_activeBOOLEANDEFAULTTRUE,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Create function to register transformation ruleCREATEORREPLACEFUNCTIONregister_transformation_rule(p_rule_nameVARCHAR(100),p_source_tableVARCHAR(100),p_target_tableVARCHAR(100),p_transformation_logicJSONB,p_validation_rulesJSONBDEFAULT'{}')RETURNSVOIDAS$$BEGININSERTINTOtransformation_rules(rule_name,source_table,target_table,transformation_logic,validation_rules)VALUES(p_rule_name,p_source_table,p_target_table,p_transformation_logic,p_validation_rules)ONCONFLICT(rule_name)DOUPDATESETsource_table=EXCLUDED.source_table,target_table=EXCLUDED.target_table,transformation_logic=EXCLUDED.transformation_logic,validation_rules=EXCLUDED.validation_rules;END;$$LANGUAGEplpgsql;-- Create function to apply transformationCREATEORREPLACEFUNCTIONapply_transformation(p_rule_nameVARCHAR(100),p_source_dataJSONB)RETURNSJSONBAS$$DECLARErule_recordRECORD;transformed_dataJSONB;field_mappingJSONB;field_nameTEXT;field_valueJSONB;validation_resultBOOLEAN;BEGIN-- Get transformation ruleSELECT*INTOrule_recordFROMtransformation_rulesWHERErule_name=p_rule_nameANDis_active=TRUE;IFrule_recordISNULLTHENRAISEEXCEPTION'Transformation rule % not found or inactive',p_rule_name;ENDIF;-- Get field mappingfield_mapping:=rule_record.transformation_logic->'field_mapping';transformed_data:='{}'::JSONB;-- Apply field transformationsFORfield_name,field_valueINSELECTkey,valueFROMjsonb_each(field_mapping)LOOP-- Apply transformation logicCASEfield_value->>'type'WHEN'direct'THENtransformed_data:=transformed_data||jsonb_build_object(field_name,p_source_data->(field_value->>'source_field'));WHEN'calculated'THEN-- Apply calculation logictransformed_data:=transformed_data||jsonb_build_object(field_name,p_source_data->(field_value->>'source_field'));WHEN'constant'THENtransformed_data:=transformed_data||jsonb_build_object(field_name,field_value->>'value');ENDCASE;ENDLOOP;-- Apply validation rulesIFrule_record.validation_rules!='{}'THENvalidation_result:=validate_data(transformed_data,rule_record.validation_rules);IFNOTvalidation_resultTHENRAISEEXCEPTION'Data validation failed for rule %',p_rule_name;ENDIF;ENDIF;RETURNtransformed_data;END;$$LANGUAGEplpgsql;
-- Create data targets tableCREATETABLEdata_targets(idSERIALPRIMARYKEY,target_nameVARCHAR(100)UNIQUENOTNULL,target_typeVARCHAR(50)NOTNULL,connection_configJSONBNOTNULL,target_schemaJSONB,is_activeBOOLEANDEFAULTTRUE,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Create function to register data targetCREATEORREPLACEFUNCTIONregister_data_target(p_target_nameVARCHAR(100),p_target_typeVARCHAR(50),p_connection_configJSONB,p_target_schemaJSONBDEFAULTNULL)RETURNSVOIDAS$$BEGININSERTINTOdata_targets(target_name,target_type,connection_config,target_schema)VALUES(p_target_name,p_target_type,p_connection_config,p_target_schema)ONCONFLICT(target_name)DOUPDATESETtarget_type=EXCLUDED.target_type,connection_config=EXCLUDED.connection_config,target_schema=EXCLUDED.target_schema;END;$$LANGUAGEplpgsql;-- Create function to load dataCREATEORREPLACEFUNCTIONload_data(p_target_nameVARCHAR(100),p_dataJSONB,p_load_modeVARCHAR(20)DEFAULT'insert')RETURNSINTEGERAS$$DECLAREtarget_recordRECORD;rows_affectedINTEGER;BEGIN-- Get target configurationSELECT*INTOtarget_recordFROMdata_targetsWHEREtarget_name=p_target_nameANDis_active=TRUE;IFtarget_recordISNULLTHENRAISEEXCEPTION'Data target % not found or inactive',p_target_name;ENDIF;-- Apply load modeCASEp_load_modeWHEN'insert'THEN-- Insert dataEXECUTEformat('INSERT INTO %I (data) VALUES (%L)',target_record.target_name,p_data);rows_affected:=1;WHEN'upsert'THEN-- Upsert dataEXECUTEformat('INSERT INTO %I (data) VALUES (%L) ON CONFLICT DO UPDATE SET data = EXCLUDED.data',target_record.target_name,p_data);rows_affected:=1;WHEN'update'THEN-- Update dataEXECUTEformat('UPDATE %I SET data = %L WHERE id = %L',target_record.target_name,p_data,p_data->>'id');rows_affected:=1;ELSERAISEEXCEPTION'Unknown load mode: %',p_load_mode;ENDCASE;RETURNrows_affected;END;$$LANGUAGEplpgsql;
-- Create CDC configuration tableCREATETABLEcdc_config(idSERIALPRIMARYKEY,table_nameVARCHAR(100)NOTNULL,cdc_enabledBOOLEANDEFAULTTRUE,capture_columnsTEXT[],exclude_columnsTEXT[],created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Create function to enable CDCCREATEORREPLACEFUNCTIONenable_cdc(p_table_nameVARCHAR(100),p_capture_columnsTEXT[]DEFAULTNULL,p_exclude_columnsTEXT[]DEFAULTNULL)RETURNSVOIDAS$$BEGININSERTINTOcdc_config(table_name,capture_columns,exclude_columns)VALUES(p_table_name,p_capture_columns,p_exclude_columns)ONCONFLICT(table_name)DOUPDATESETcdc_enabled=TRUE,capture_columns=EXCLUDED.capture_columns,exclude_columns=EXCLUDED.exclude_columns;END;$$LANGUAGEplpgsql;-- Create function to capture changesCREATEORREPLACEFUNCTIONcapture_changes(p_table_nameVARCHAR(100),p_operationVARCHAR(10),p_old_dataJSONB,p_new_dataJSONB)RETURNSVOIDAS$$DECLAREcdc_recordRECORD;change_dataJSONB;BEGIN-- Get CDC configurationSELECT*INTOcdc_recordFROMcdc_configWHEREtable_name=p_table_nameANDcdc_enabled=TRUE;IFcdc_recordISNULLTHENRETURN;ENDIF;-- Build change datachange_data:=jsonb_build_object('table_name',p_table_name,'operation',p_operation,'timestamp',CURRENT_TIMESTAMP,'old_data',p_old_data,'new_data',p_new_data);-- Store changeINSERTINTOchange_log(table_name,operation,change_data)VALUES(p_table_name,p_operation,change_data);END;$$LANGUAGEplpgsql;
-- Create streaming configuration tableCREATETABLEstreaming_config(idSERIALPRIMARYKEY,stream_nameVARCHAR(100)UNIQUENOTNULL,source_tableVARCHAR(100)NOTNULL,target_systemVARCHAR(100)NOTNULL,stream_configJSONBNOTNULL,is_activeBOOLEANDEFAULTTRUE,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Create function to configure streamCREATEORREPLACEFUNCTIONconfigure_stream(p_stream_nameVARCHAR(100),p_source_tableVARCHAR(100),p_target_systemVARCHAR(100),p_stream_configJSONB)RETURNSVOIDAS$$BEGININSERTINTOstreaming_config(stream_name,source_table,target_system,stream_config)VALUES(p_stream_name,p_source_table,p_target_system,p_stream_config)ONCONFLICT(stream_name)DOUPDATESETsource_table=EXCLUDED.source_table,target_system=EXCLUDED.target_system,stream_config=EXCLUDED.stream_config;END;$$LANGUAGEplpgsql;-- Create function to process streamCREATEORREPLACEFUNCTIONprocess_stream(p_stream_nameVARCHAR(100),p_batch_sizeINTEGERDEFAULT100)RETURNSINTEGERAS$$DECLAREstream_recordRECORD;processed_countINTEGER:=0;batch_dataJSONB[];BEGIN-- Get stream configurationSELECT*INTOstream_recordFROMstreaming_configWHEREstream_name=p_stream_nameANDis_active=TRUE;IFstream_recordISNULLTHENRAISEEXCEPTION'Stream % not found or inactive',p_stream_name;ENDIF;-- Process stream batch-- Implementation depends on target system-- This is a placeholder for actual streaming logicRETURNprocessed_count;END;$$LANGUAGEplpgsql;
-- Create validation rules tableCREATETABLEvalidation_rules(idSERIALPRIMARYKEY,rule_nameVARCHAR(100)UNIQUENOTNULL,rule_typeVARCHAR(50)NOTNULL,rule_definitionJSONBNOTNULL,error_messageTEXT,is_activeBOOLEANDEFAULTTRUE,created_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Create function to register validation ruleCREATEORREPLACEFUNCTIONregister_validation_rule(p_rule_nameVARCHAR(100),p_rule_typeVARCHAR(50),p_rule_definitionJSONB,p_error_messageTEXTDEFAULTNULL)RETURNSVOIDAS$$BEGININSERTINTOvalidation_rules(rule_name,rule_type,rule_definition,error_message)VALUES(p_rule_name,p_rule_type,p_rule_definition,p_error_message)ONCONFLICT(rule_name)DOUPDATESETrule_type=EXCLUDED.rule_type,rule_definition=EXCLUDED.rule_definition,error_message=EXCLUDED.error_message;END;$$LANGUAGEplpgsql;-- Create function to validate dataCREATEORREPLACEFUNCTIONvalidate_data(p_dataJSONB,p_validation_rulesJSONB)RETURNSBOOLEANAS$$DECLARErule_nameTEXT;rule_definitionJSONB;field_nameTEXT;field_valueJSONB;validation_resultBOOLEAN;BEGIN-- Apply validation rulesFORrule_name,rule_definitionINSELECTkey,valueFROMjsonb_each(p_validation_rules)LOOPfield_name:=rule_definition->>'field';field_value:=p_data->field_name;-- Apply validation based on rule typeCASErule_definition->>'type'WHEN'required'THENIFfield_valueISNULLORfield_value='null'THENRETURNFALSE;ENDIF;WHEN'format'THENIFrule_definition->>'format'='email'THENIFNOT(field_value#>>'{}'~*'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$')THENRETURNFALSE;ENDIF;ENDIF;WHEN'range'THENIFfield_valueISNOTNULLTHENIF(rule_definition->>'min')::NUMERIC>(field_value#>>'{}')::NUMERICOR(rule_definition->>'max')::NUMERIC<(field_value#>>'{}')::NUMERICTHENRETURNFALSE;ENDIF;ENDIF;WHEN'pattern'THENIFfield_valueISNOTNULLTHENIFNOT(field_value#>>'{}'~rule_definition->>'pattern')THENRETURNFALSE;ENDIF;ENDIF;ENDCASE;ENDLOOP;RETURNTRUE;END;$$LANGUAGEplpgsql;
-- Create data quality metrics tableCREATETABLEdata_quality_metrics(idSERIALPRIMARYKEY,table_nameVARCHAR(100)NOTNULL,metric_nameVARCHAR(100)NOTNULL,metric_valueNUMERICNOTNULL,threshold_valueNUMERIC,is_healthyBOOLEAN,recorded_atTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP);-- Create function to record data quality metricsCREATEORREPLACEFUNCTIONrecord_data_quality_metrics(p_table_nameVARCHAR(100),p_metric_nameVARCHAR(100),p_metric_valueNUMERIC,p_threshold_valueNUMERICDEFAULTNULL)RETURNSVOIDAS$$DECLAREis_healthyBOOLEAN;BEGIN-- Determine if metric is healthyIFp_threshold_valueISNOTNULLTHENis_healthy:=p_metric_value<=p_threshold_value;ELSEis_healthy:=TRUE;ENDIF;-- Record metricINSERTINTOdata_quality_metrics(table_name,metric_name,metric_value,threshold_value,is_healthy)VALUES(p_table_name,p_metric_name,p_metric_value,p_threshold_value,is_healthy);END;$$LANGUAGEplpgsql;-- Create function to get data quality reportCREATEORREPLACEFUNCTIONget_data_quality_report(p_table_nameVARCHAR(100),p_start_dateTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP-INTERVAL'1 day',p_end_dateTIMESTAMPTZDEFAULTCURRENT_TIMESTAMP)RETURNSTABLE(metric_nameVARCHAR(100),avg_metric_valueNUMERIC,max_metric_valueNUMERIC,min_metric_valueNUMERIC,healthy_percentageNUMERIC)AS$$BEGINRETURNQUERYSELECTdqm.metric_name,AVG(dqm.metric_value)asavg_metric_value,MAX(dqm.metric_value)asmax_metric_value,MIN(dqm.metric_value)asmin_metric_value,(COUNT(*)FILTER(WHEREdqm.is_healthy=TRUE)::NUMERIC/COUNT(*)::NUMERIC*100)ashealthy_percentageFROMdata_quality_metricsdqmWHEREdqm.table_name=p_table_nameANDdqm.recorded_atBETWEENp_start_dateANDp_end_dateGROUPBYdqm.metric_nameORDERBYdqm.metric_name;END;$$LANGUAGEplpgsql;