structured_data_to_sql 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a50afe6c834dcd44e699032caa0cdc7edd95b6bb041ccdd24ff2a4e9baf95ea
4
- data.tar.gz: 2ed49f9f4dedd7be4e163006c75cccaca849e8cab58a487526b00c3326f0c184
3
+ metadata.gz: 0c7a2d7a571374df01b77f059c243d1ddf43ab4ac51fe85f21c3b5a8ba7d1ed4
4
+ data.tar.gz: bca5b0b6e07ff5c7de2c254bcfa336b27f9ef35c949a6b1e3db4618a61820030
5
5
  SHA512:
6
- metadata.gz: 69ec834c19d138f85dc1182d6b2b057b9e6e07dd52a4f6850312216e63c9567603dd0aa8cfd3b817a8e2c14b89c5bd6f5d770eb6f294db85c60cb3f160cfe0e7
7
- data.tar.gz: 2f671632b40604564a48a55650cd4b07ffd95ddeb8e2046cb2972f37c89af283b9f0cf5b01a7cfd1e05d19b875183e48f225bff7752959f4bdae03f3820a217f
6
+ metadata.gz: 7673f7ac81093a5c3e533b300e71f422a1026ac6c814270f400720f571b09d6918b6badffe99c7c8419983071a68cba51aac951bf7c1348c78c9a48c6afc8624
7
+ data.tar.gz: de4c881ae651cb0ff5ef6e9973a44d3e90d9763a6ea7521e34a7174c661bd361bb30c0aa97333ff387aa6dd1d2428a8f9958e12d4de8b75ea6ec9d1007bbbd5d
@@ -17,8 +17,8 @@ module StructuredDataToSql
17
17
  NAME = :khoros_api_export
18
18
  # Bumped in lockstep with PROFILE_VERSION in the Khoros converter's
19
19
  # KhorosApiExportContentStaging whenever a canonical table's shape or
20
- # semantics change. Version 3 adds source-message view counts.
21
- VERSION = 3
20
+ # semantics change. Version 4 adds optional API subscriptions.
21
+ VERSION = 4
22
22
  PREFIX = "discourse_khoros_api"
23
23
  METADATA_TABLE = "_structured_data_to_sql_profiles"
24
24
  # Explicit storage options on every canonical table so they never
@@ -62,6 +62,7 @@ module StructuredDataToSql
62
62
  attachments
63
63
  files
64
64
  source_messages
65
+ subscriptions
65
66
  ].map { |name| "#{PREFIX}_#{name}" }.freeze
66
67
  USER_STRING_FIELDS = {
67
68
  id: %w[data_id],
@@ -222,6 +223,21 @@ module StructuredDataToSql
222
223
  }
223
224
  }.freeze
224
225
  OPTIONAL = {
226
+ "subscriptions" => {
227
+ required: {
228
+ subscription_id: %w[id],
229
+ context_user_id: %w[context_user_id],
230
+ subscriber_id: %w[data_subscriber_id],
231
+ target_type: %w[data_target_type],
232
+ target_id: %w[data_target_id]
233
+ },
234
+ indexed: {
235
+ subscription_id: %w[id],
236
+ context_user_id: %w[context_user_id],
237
+ subscriber_id: %w[data_subscriber_id],
238
+ target_id: %w[data_target_id]
239
+ }
240
+ },
225
241
  "user_profiles" => {
226
242
  required: {
227
243
  user_id: %w[id]
@@ -933,9 +949,10 @@ module StructuredDataToSql
933
949
  out.write("DROP TABLE IF EXISTS `#{METADATA_TABLE}`;\n")
934
950
  end
935
951
 
936
- def initialize(table_columns)
952
+ def initialize(table_columns, supplied_collections: [])
937
953
  @table_columns =
938
954
  table_columns.transform_values { |value| Array(value).map(&:to_s) }
955
+ @supplied_collections = supplied_collections
939
956
  end
940
957
 
941
958
  def write(out)
@@ -960,6 +977,7 @@ module StructuredDataToSql
960
977
  create_attachments
961
978
  create_files
962
979
  create_source_messages
980
+ create_subscriptions
963
981
  create_metadata
964
982
  ensure
965
983
  @out = nil
@@ -1997,18 +2015,70 @@ module StructuredDataToSql
1997
2015
  add_index(table, "idx_board_id", %w[board_id])
1998
2016
  end
1999
2017
 
2018
+ def create_subscriptions
2019
+ table = "#{PREFIX}_subscriptions"
2020
+ unless canonical_source?(
2021
+ "subscriptions",
2022
+ "context_user_id",
2023
+ "data_subscriber_id",
2024
+ "data_target_type",
2025
+ "data_target_id"
2026
+ )
2027
+ create_empty(
2028
+ table,
2029
+ [
2030
+ "`id` VARCHAR(255) NOT NULL",
2031
+ "`context_user_id` VARCHAR(255) NOT NULL",
2032
+ "`subscriber_id` VARCHAR(255) NOT NULL",
2033
+ "`target_type` VARCHAR(255) NOT NULL",
2034
+ "`target_id` VARCHAR(255) NOT NULL",
2035
+ "`source_sid` BIGINT NOT NULL"
2036
+ ],
2037
+ indexes: [
2038
+ "PRIMARY KEY (`id`, `context_user_id`)",
2039
+ "KEY `idx_subscriber_id` (`subscriber_id`)"
2040
+ ]
2041
+ )
2042
+ return
2043
+ end
2044
+
2045
+ statement(<<~SQL)
2046
+ CREATE TABLE `#{table}` #{TABLE_OPTIONS} AS
2047
+ SELECT
2048
+ #{key("s.id")} AS id,
2049
+ #{key("s.context_user_id")} AS context_user_id,
2050
+ #{key("s.data_subscriber_id")} AS subscriber_id,
2051
+ #{key("s.data_target_type")} AS target_type,
2052
+ #{key("s.data_target_id")} AS target_id,
2053
+ s._sid AS source_sid
2054
+ FROM (
2055
+ SELECT source_row.*,
2056
+ ROW_NUMBER() OVER (
2057
+ PARTITION BY source_row.id, source_row.context_user_id
2058
+ ORDER BY source_row._sid DESC
2059
+ ) AS occurrence_rn
2060
+ FROM `subscriptions` source_row
2061
+ ) s
2062
+ WHERE s.occurrence_rn = 1
2063
+ AND #{present("s.id", "s.context_user_id", "s.data_subscriber_id", "s.data_target_type", "s.data_target_id")}
2064
+ SQL
2065
+ add_primary_key(table, %w[id context_user_id])
2066
+ add_index(table, "idx_subscriber_id", %w[subscriber_id])
2067
+ end
2068
+
2000
2069
  def create_metadata
2001
2070
  statement(<<~SQL)
2002
2071
  CREATE TABLE `#{METADATA_TABLE}` (
2003
2072
  `profile` VARCHAR(64) NOT NULL,
2004
2073
  `profile_version` BIGINT NOT NULL,
2005
2074
  `tool_version` VARCHAR(64) NOT NULL,
2075
+ `subscriptions_supplied` TINYINT(1) NOT NULL,
2006
2076
  PRIMARY KEY (`profile`)
2007
2077
  ) #{TABLE_OPTIONS}
2008
2078
  SQL
2009
2079
  statement(<<~SQL)
2010
- INSERT INTO `#{METADATA_TABLE}` (`profile`, `profile_version`, `tool_version`)
2011
- VALUES ('khoros_api_export', #{VERSION}, '#{StructuredDataToSql::VERSION.gsub("'", "''")}')
2080
+ INSERT INTO `#{METADATA_TABLE}` (`profile`, `profile_version`, `tool_version`, `subscriptions_supplied`)
2081
+ VALUES ('khoros_api_export', #{VERSION}, '#{StructuredDataToSql::VERSION.gsub("'", "''")}', #{@supplied_collections.include?("subscriptions") ? 1 : 0})
2012
2082
  SQL
2013
2083
  end
2014
2084
  end
@@ -192,6 +192,8 @@ module StructuredDataToSql
192
192
  raise UsageError, "No JSON files found in #{source}" if files.empty?
193
193
 
194
194
  files_to_process, skipped = files.partition { |file| process_file?(file) }
195
+ @profile_supplied_collections =
196
+ files_to_process.map { |file| json_basename(file) }.to_set if @profile
195
197
  @stats[:files_skipped] += skipped.length
196
198
  if files_to_process.empty?
197
199
  raise UsageError,
@@ -693,7 +695,15 @@ module StructuredDataToSql
693
695
  ).each_record(
694
696
  counting,
695
697
  recover: @recover_truncated,
696
- ndjson: @ndjson,
698
+ ndjson:
699
+ (
700
+ if @ndjson == :auto &&
701
+ path.to_s.match?(/\.(?:ndjson|jsonl)(?:\.gz)?\z/)
702
+ true
703
+ else
704
+ @ndjson
705
+ end
706
+ ),
697
707
  &block
698
708
  )
699
709
  end
@@ -784,7 +794,10 @@ module StructuredDataToSql
784
794
  @profile_validator.warnings
785
795
  end
786
796
  warnings.each { |warning| emit_warning(warning) }
787
- profile_class.new(@profile_tables).write(out)
797
+ profile_class.new(
798
+ @profile_tables,
799
+ supplied_collections: @profile_supplied_collections
800
+ ).write(out)
788
801
  end
789
802
 
790
803
  def write_profile_preamble(out)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StructuredDataToSql
4
- VERSION = "0.2.1"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: structured_data_to_sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Discourse Team