recursifier 0.1.1 → 0.1.2

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: 7222c9df26b3ed88f80291cc7a6572abfca30bd84924bf8c32f399a09bf0aa71
4
- data.tar.gz: c5cdcd742ceee2def0c7c1b199fbd7ad9186c3632d3ad194fa670ff1311628f2
3
+ metadata.gz: 70abf15924be32d252f28bd29f78b0e0b4c6308b28f3372ff9fd9b737bf0850c
4
+ data.tar.gz: ee1fdea7fe022b9b4846a02c02b7abfc33bdaaa6c087f7f1dd7093121acde3b5
5
5
  SHA512:
6
- metadata.gz: 8d4accda36465e79b607b38da901ae05e13e82bc87273540896b233074395aafd55315493990f551ecfc14205efc6d773f1c163ac3d623544b2ba1399f53a516
7
- data.tar.gz: c834aaa17bc2279df4b9cd324cbdd2d1a31a1704a900353aedc990351059ded8aac01e26adbe3baf4cb7eecd4406661324b5c361a479967abacc9d20b2cb0ddc
6
+ metadata.gz: 14556fc8c7937797eb709a2bd7185aa8a9d1d3249c87dceb4064c33336f524864f855b78e28918babe9bad2b59e11cc198972fe507df92937223817ca74253f4
7
+ data.tar.gz: 8f5ef9e9065266e2257058584aec8bf80b1d9efe747070ac925415d8a4ccaf9daf675fda1203cc1989111539cdb095dd4fdec204693f050e77d533876cbe1ee6
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Recursifier
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
data/lib/recursifier.rb CHANGED
@@ -1,29 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "recursifier/version"
3
+ require_relative 'recursifier/version'
4
4
 
5
5
  module Recursifier
6
6
  module RecursiveQuery
7
-
8
7
  class InvalidQueryError < StandardError; end
9
8
 
10
9
  def self.fetch_hierarchy(table_name, parent_matching_column, sub_matching_column, start_id, filters = {}, selected_columns = [], max_depth = 10, current_depth = 0)
11
-
12
- # Validate inputs
13
- raise InvalidQueryError, "Table name must be a string" unless table_name.is_a?(String)
14
- raise InvalidQueryError, "Selected columns must be an array of strings" unless selected_columns.is_a?(Array) && selected_columns.all? { |col| col.is_a?(String) }
15
-
10
+
11
+ # Validate inputs
12
+ raise InvalidQueryError, 'Table name must be a string' unless table_name.is_a?(String)
13
+ unless selected_columns.is_a?(Array) && selected_columns.all? { |col| col.is_a?(String) }
14
+ raise InvalidQueryError, 'Selected columns must be an array of strings'
15
+ end
16
+
16
17
  begin
17
18
  # Check if the current depth exceeds the maximum depth limit
18
- if current_depth > max_depth
19
- return { error: "Maximum recursion depth exceeded" }
20
- end
19
+ return { error: 'Maximum recursion depth exceeded' } if current_depth > max_depth
21
20
 
22
21
  # Convert filters hash into SQL conditions
23
22
  filter_conditions = filters.map { |key, value| "#{key} = '#{value}'" }.join(' AND ')
24
23
 
25
24
  # Convert selected_columns array into comma-separated column names
26
- selected_columns_sub_str = selected_columns.empty? ? '*' : selected_columns.map { |col| "t.#{col}" }.join(', ')
25
+ selected_columns_sub_str = selected_columns.empty? ? 't.*' : selected_columns.map { |col| "t.#{col}" }.join(', ')
27
26
 
28
27
  selected_columns_str = selected_columns.empty? ? '*' : selected_columns.join(', ')
29
28
 
@@ -39,20 +38,94 @@ module Recursifier
39
38
  SQL
40
39
 
41
40
  # Executing the query and return the result
42
- ActiveRecord::Base.connection.execute(query)
41
+ data = ActiveRecord::Base.connection.execute(query)
42
+ HierarchicalData.new(data, parent_matching_column, sub_matching_column)
43
43
 
44
44
  rescue ActiveRecord::StatementInvalid => e
45
- if e.message.include?("statement timeout")
46
- # Handle statement timeout error
47
- error_message = "Statement Timeout: #{e.message}"
48
- else
49
- # Handle other errors
50
- error_message = "Error: #{e.message}"
51
- end
45
+ error_message = if e.message.include?('statement timeout')
46
+ # Handle statement timeout error
47
+ "Statement Timeout: #{e.message}"
48
+ else
49
+ # Handle other errors
50
+ "Error: #{e.message}"
51
+ end
52
52
 
53
53
  # Return the error message as part of the response
54
54
  { error: error_message }
55
55
  end
56
56
  end
57
+
58
+ class HierarchicalData
59
+ attr_reader :data, :parent_matching_column, :sub_matching_column
60
+
61
+ def initialize(data, parent_match, sub_match)
62
+ @data = data
63
+ @parent_match = parent_match
64
+ @sub_match = sub_match
65
+ end
66
+
67
+ def to_visualize
68
+ parsed_data = JSON.parse(@data.to_json)
69
+
70
+ html = <<~HTML
71
+ <!DOCTYPE html>
72
+ <html lang="en">
73
+ <head>
74
+ <meta charset="UTF-8">
75
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
76
+ <title>Hierarchical Data Visualization</title>
77
+ <style>
78
+ .google-visualization-orgchart-node {
79
+ animation: fade-in 0.5s ease-out;
80
+ }
81
+ @keyframes fade-in {
82
+ 0% { opacity: 0; }
83
+ 100% { opacity: 1; }
84
+ }
85
+ .google-visualization-orgchart-node:hover {
86
+ transform: scale(1.1); /* Scale up the node on hover */
87
+ transition: transform 0.3s ease; /* Add smooth transition */
88
+ }
89
+ </style>
90
+
91
+ <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
92
+ <script type="text/javascript">
93
+ google.charts.load('current', {packages: ['orgchart']});
94
+ google.charts.setOnLoadCallback(drawChart);
95
+ function drawChart() {
96
+ var data = new google.visualization.DataTable();
97
+ data.addColumn('string', 'Node');
98
+ data.addColumn('string', 'Parent');
99
+ data.addRows([
100
+ #{generate_rows(parsed_data)}
101
+ ]);
102
+ var chart = new google.visualization.OrgChart(document.getElementById('visualization'));
103
+ chart.draw(data, {allowHtml: true});
104
+ }
105
+ </script>
106
+ </head>
107
+ <body>
108
+ <div id="visualization" style="width: 100%; height: 100%;"></div>
109
+ </body>
110
+ </html>
111
+ HTML
112
+
113
+ html
114
+ end
115
+
116
+ def get_data
117
+ @data
118
+ end
119
+
120
+ private
121
+
122
+ def generate_rows(data)
123
+ rows = ''
124
+ data.each do |row|
125
+ rows += "['ID: #{row[@parent_match.to_s]}', 'ID: #{row[@sub_match.to_s]}'],"
126
+ end
127
+ rows
128
+ end
129
+ end
57
130
  end
58
131
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: recursifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jana
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-09 00:00:00.000000000 Z
11
+ date: 2024-03-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Recursifier is a Ruby gem designed to simplify and optimize recursive
14
14
  querying of hierarchical data in PostgreSQL databases, particularly within Ruby