data_download_schema.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package database
  2. import (
  3. "fmt"
  4. "gorm.io/gorm"
  5. )
  6. const dataDownloadSchemaVersion int64 = 2
  7. var dataDownloadSchemaV1 = []string{
  8. `CREATE TABLE IF NOT EXISTS data_download_content_state (
  9. document_id varchar(64) PRIMARY KEY,
  10. document_kind varchar(32) NOT NULL,
  11. content_generation bigint NOT NULL DEFAULT 0,
  12. schema_version varchar(32) NOT NULL DEFAULT 'v1',
  13. row_count bigint NOT NULL DEFAULT 0,
  14. checksum char(64) NOT NULL DEFAULT '',
  15. source_fetched_at timestamptz NOT NULL,
  16. updated_at timestamptz NOT NULL DEFAULT now()
  17. )`,
  18. `CREATE TABLE IF NOT EXISTS data_download_power_flow_meta (
  19. document_id varchar(64) PRIMARY KEY REFERENCES data_download_content_state(document_id) ON DELETE CASCADE,
  20. site_sn varchar(64) NOT NULL,
  21. local_date date NOT NULL,
  22. timezone varchar(80) NOT NULL
  23. )`,
  24. `CREATE TABLE IF NOT EXISTS data_download_power_flow_point (
  25. document_id varchar(64) NOT NULL REFERENCES data_download_content_state(document_id) ON DELETE CASCADE,
  26. point_index integer NOT NULL,
  27. sampled_at timestamptz,
  28. payload jsonb NOT NULL,
  29. PRIMARY KEY(document_id, point_index)
  30. )`,
  31. `CREATE TABLE IF NOT EXISTS data_download_mqtt_log_entry (
  32. document_id varchar(64) NOT NULL REFERENCES data_download_content_state(document_id) ON DELETE CASCADE,
  33. row_index integer NOT NULL,
  34. occurred_at timestamptz,
  35. subtype varchar(80) NOT NULL DEFAULT '',
  36. payload jsonb NOT NULL,
  37. PRIMARY KEY(document_id, row_index)
  38. )`,
  39. `CREATE TABLE IF NOT EXISTS data_download_event_alarm_entry (
  40. document_id varchar(64) NOT NULL REFERENCES data_download_content_state(document_id) ON DELETE CASCADE,
  41. row_index integer NOT NULL,
  42. occurred_at timestamptz,
  43. payload jsonb NOT NULL,
  44. PRIMARY KEY(document_id, row_index)
  45. )`,
  46. `CREATE TABLE IF NOT EXISTS data_download_update_log_entry (
  47. document_id varchar(64) NOT NULL REFERENCES data_download_content_state(document_id) ON DELETE CASCADE,
  48. row_index integer NOT NULL,
  49. device_sn varchar(64) NOT NULL DEFAULT '',
  50. device_type varchar(80) NOT NULL DEFAULT '',
  51. occurred_at timestamptz,
  52. payload jsonb NOT NULL,
  53. PRIMARY KEY(document_id, row_index)
  54. )`,
  55. `CREATE INDEX IF NOT EXISTS idx_dd_pf_site_date ON data_download_power_flow_meta(site_sn, local_date)`,
  56. `CREATE INDEX IF NOT EXISTS idx_dd_mqtt_occurred ON data_download_mqtt_log_entry(document_id, occurred_at)`,
  57. `CREATE INDEX IF NOT EXISTS idx_dd_event_occurred ON data_download_event_alarm_entry(document_id, occurred_at)`,
  58. `CREATE INDEX IF NOT EXISTS idx_dd_update_device ON data_download_update_log_entry(document_id, device_sn, device_type)`,
  59. `ALTER TABLE data_download_content_state ADD COLUMN IF NOT EXISTS content_checksum char(64) NOT NULL DEFAULT ''`,
  60. `ALTER TABLE data_download_content_state ALTER COLUMN schema_version DROP DEFAULT`,
  61. `ALTER TABLE data_download_content_state ALTER COLUMN schema_version TYPE varchar(32) USING schema_version::text`,
  62. `ALTER TABLE data_download_content_state ALTER COLUMN schema_version SET DEFAULT 'v1'`,
  63. `DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'chk_dd_document_kind') THEN ALTER TABLE data_download_content_state ADD CONSTRAINT chk_dd_document_kind CHECK (document_kind IN ('power_flow','mqtt_log','event_alarm','update_log')); END IF; END $$`,
  64. `ALTER TABLE data_download_power_flow_meta ADD COLUMN IF NOT EXISTS reported_index integer NOT NULL DEFAULT 0`,
  65. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS seq integer`,
  66. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS device_time_local timestamp without time zone`,
  67. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS device_time_utc timestamptz`,
  68. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS power_fhp real`,
  69. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS power_gen real`,
  70. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS power_load real`,
  71. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS power_sun real`,
  72. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS power_uti real`,
  73. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS soc real`,
  74. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS kwh_total real`,
  75. `ALTER TABLE data_download_power_flow_point ADD COLUMN IF NOT EXISTS run_status integer`,
  76. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS cmd_type varchar(32)`,
  77. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS cmd_name varchar(255)`,
  78. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS gateway_id varchar(64)`,
  79. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS gateway_type varchar(80)`,
  80. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS gateway_status varchar(80)`,
  81. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS active_status varchar(80)`,
  82. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS device_time_raw text`,
  83. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS event_time_raw text`,
  84. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS device_time_local timestamp without time zone`,
  85. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS event_time_utc timestamptz`,
  86. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS log_data_raw text`,
  87. `ALTER TABLE data_download_mqtt_log_entry ADD COLUMN IF NOT EXISTS log_data_json jsonb`,
  88. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS source_id varchar(80)`,
  89. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS cmd_type varchar(80)`,
  90. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS cmd_name varchar(255)`,
  91. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS gateway_id varchar(64)`,
  92. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS log_type varchar(32)`,
  93. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS alarm_code varchar(80)`,
  94. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS log_name text`,
  95. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS log_data_raw text`,
  96. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS log_data_json jsonb`,
  97. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS device_time_raw text`,
  98. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS start_time_raw text`,
  99. `ALTER TABLE data_download_event_alarm_entry ADD COLUMN IF NOT EXISTS end_time_raw text`,
  100. `CREATE TABLE IF NOT EXISTS data_download_update_order (
  101. document_id varchar(64) NOT NULL REFERENCES data_download_content_state(document_id) ON DELETE CASCADE,
  102. order_no varchar(128) NOT NULL, payload jsonb NOT NULL,
  103. PRIMARY KEY(document_id, order_no)
  104. )`,
  105. `CREATE TABLE IF NOT EXISTS data_download_update_device_version (
  106. document_id varchar(64) NOT NULL REFERENCES data_download_content_state(document_id) ON DELETE CASCADE,
  107. order_no varchar(128) NOT NULL, scope varchar(32) NOT NULL, device_sn varchar(64) NOT NULL,
  108. name varchar(255) NOT NULL, payload jsonb NOT NULL,
  109. PRIMARY KEY(document_id, order_no, scope, device_sn, name)
  110. )`,
  111. `CREATE TABLE IF NOT EXISTS data_download_ahub_update (
  112. document_id varchar(64) NOT NULL REFERENCES data_download_content_state(document_id) ON DELETE CASCADE,
  113. order_no varchar(128) NOT NULL, ahub_sn varchar(64) NOT NULL, payload jsonb NOT NULL,
  114. PRIMARY KEY(document_id, order_no, ahub_sn)
  115. )`,
  116. `CREATE TABLE IF NOT EXISTS data_download_ahub_update_detail (
  117. document_id varchar(64) NOT NULL REFERENCES data_download_content_state(document_id) ON DELETE CASCADE,
  118. order_no varchar(128) NOT NULL, ahub_sn varchar(64) NOT NULL, file_order varchar(128) NOT NULL,
  119. file_name varchar(255) NOT NULL, payload jsonb NOT NULL,
  120. PRIMARY KEY(document_id, order_no, ahub_sn, file_order, file_name)
  121. )`,
  122. `CREATE INDEX IF NOT EXISTS idx_dd_mqtt_local ON data_download_mqtt_log_entry(document_id, device_time_local, row_index)`,
  123. `CREATE INDEX IF NOT EXISTS idx_dd_event_alarm ON data_download_event_alarm_entry(document_id, log_type, alarm_code)`,
  124. }
  125. func MigrateDataDownloadSchema(db *gorm.DB) error {
  126. if db == nil {
  127. return fmt.Errorf("PostgreSQL is not initialized")
  128. }
  129. return db.Transaction(func(tx *gorm.DB) error {
  130. if err := tx.Exec(`CREATE TABLE IF NOT EXISTS data_download_schema_migrations (
  131. version bigint PRIMARY KEY,
  132. applied_at timestamptz NOT NULL DEFAULT now()
  133. )`).Error; err != nil {
  134. return err
  135. }
  136. var count int64
  137. if err := tx.Raw("SELECT count(*) FROM data_download_schema_migrations WHERE version = ?", dataDownloadSchemaVersion).Scan(&count).Error; err != nil {
  138. return err
  139. }
  140. if count != 0 {
  141. return nil
  142. }
  143. for _, statement := range dataDownloadSchemaV1 {
  144. if err := tx.Exec(statement).Error; err != nil {
  145. return fmt.Errorf("apply data-download schema v%d: %w", dataDownloadSchemaVersion, err)
  146. }
  147. }
  148. return tx.Exec("INSERT INTO data_download_schema_migrations(version) VALUES (?)", dataDownloadSchemaVersion).Error
  149. })
  150. }