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 +4 -4
- data/lib/recursifier/version.rb +1 -1
- data/lib/recursifier.rb +92 -19
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70abf15924be32d252f28bd29f78b0e0b4c6308b28f3372ff9fd9b737bf0850c
|
4
|
+
data.tar.gz: ee1fdea7fe022b9b4846a02c02b7abfc33bdaaa6c087f7f1dd7093121acde3b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14556fc8c7937797eb709a2bd7185aa8a9d1d3249c87dceb4064c33336f524864f855b78e28918babe9bad2b59e11cc198972fe507df92937223817ca74253f4
|
7
|
+
data.tar.gz: 8f5ef9e9065266e2257058584aec8bf80b1d9efe747070ac925415d8a4ccaf9daf675fda1203cc1989111539cdb095dd4fdec204693f050e77d533876cbe1ee6
|
data/lib/recursifier/version.rb
CHANGED
data/lib/recursifier.rb
CHANGED
@@ -1,29 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
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
|
-
|
13
|
-
raise InvalidQueryError,
|
14
|
-
|
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? ? '
|
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?(
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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.
|
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-
|
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
|