-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcreate-h1b-filtering-function.sql
More file actions
200 lines (171 loc) · 6.28 KB
/
create-h1b-filtering-function.sql
File metadata and controls
200 lines (171 loc) · 6.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
-- H1B Comprehensive Filtering Function
-- Advanced filtering with pagination for H1BFilters component
CREATE OR REPLACE FUNCTION get_h1b_filtered_applications(
filters JSON DEFAULT '{}',
page_size INTEGER DEFAULT 20,
page_number INTEGER DEFAULT 1
)
RETURNS JSON
LANGUAGE plpgsql
SECURITY DEFINER
AS $
DECLARE
result JSON;
total_count INTEGER;
offset_count INTEGER;
where_conditions TEXT[];
where_clause TEXT;
query_text TEXT;
-- Filter variables
filter_employer TEXT;
filter_status TEXT;
filter_job_title TEXT;
filter_min_salary NUMERIC;
filter_max_salary NUMERIC;
filter_search_term TEXT;
BEGIN
-- Input validation
IF page_size IS NULL OR page_size <= 0 THEN
page_size := 20;
END IF;
IF page_size > 100 THEN
page_size := 100; -- Limit page size for performance
END IF;
IF page_number IS NULL OR page_number <= 0 THEN
page_number := 1;
END IF;
-- Calculate offset
offset_count := (page_number - 1) * page_size;
-- Extract filter values from JSON (with null checks)
BEGIN
filter_employer := NULLIF(TRIM(filters->>'employer'), '');
filter_status := NULLIF(TRIM(filters->>'status'), '');
filter_job_title := NULLIF(TRIM(filters->>'jobTitle'), '');
filter_search_term := NULLIF(TRIM(filters->>'searchTerm'), '');
-- Handle numeric filters
IF (filters->>'minSalary') IS NOT NULL AND (filters->>'minSalary') != '' THEN
filter_min_salary := (filters->>'minSalary')::NUMERIC;
END IF;
IF (filters->>'maxSalary') IS NOT NULL AND (filters->>'maxSalary') != '' THEN
filter_max_salary := (filters->>'maxSalary')::NUMERIC;
END IF;
EXCEPTION
WHEN OTHERS THEN
RETURN JSON_BUILD_OBJECT(
'error', true,
'message', 'Invalid filter parameters',
'code', 'INVALID_FILTERS'
);
END;
-- Validate salary range
IF filter_min_salary IS NOT NULL AND filter_max_salary IS NOT NULL THEN
IF filter_min_salary > filter_max_salary THEN
RETURN JSON_BUILD_OBJECT(
'error', true,
'message', 'Minimum salary cannot be greater than maximum salary',
'code', 'INVALID_SALARY_RANGE'
);
END IF;
END IF;
-- Build WHERE conditions array
where_conditions := ARRAY[]::TEXT[];
-- Employer filter (partial match)
IF filter_employer IS NOT NULL THEN
where_conditions := array_append(where_conditions,
'employer_name ILIKE ' || quote_literal('%' || filter_employer || '%'));
END IF;
-- Status filter (exact match)
IF filter_status IS NOT NULL THEN
where_conditions := array_append(where_conditions,
'case_status = ' || quote_literal(filter_status));
END IF;
-- Job title filter (partial match)
IF filter_job_title IS NOT NULL THEN
where_conditions := array_append(where_conditions,
'job_title ILIKE ' || quote_literal('%' || filter_job_title || '%'));
END IF;
-- Salary filters
IF filter_min_salary IS NOT NULL THEN
where_conditions := array_append(where_conditions,
'COALESCE(wage_rate_of_pay_from, wage_rate_of_pay_to, 0) >= ' || filter_min_salary);
END IF;
IF filter_max_salary IS NOT NULL THEN
where_conditions := array_append(where_conditions,
'COALESCE(wage_rate_of_pay_from, wage_rate_of_pay_to, 0) <= ' || filter_max_salary);
END IF;
-- Text search across multiple fields
IF filter_search_term IS NOT NULL THEN
where_conditions := array_append(where_conditions,
'(employer_name ILIKE ' || quote_literal('%' || filter_search_term || '%') ||
' OR job_title ILIKE ' || quote_literal('%' || filter_search_term || '%') ||
' OR case_number ILIKE ' || quote_literal('%' || filter_search_term || '%') || ')');
END IF;
-- Combine WHERE conditions
IF array_length(where_conditions, 1) > 0 THEN
where_clause := 'WHERE ' || array_to_string(where_conditions, ' AND ');
ELSE
where_clause := '';
END IF;
-- Get total count for pagination
query_text := 'SELECT COUNT(*) FROM h1b_applications ' || where_clause;
EXECUTE query_text INTO total_count;
-- Get filtered data with pagination
query_text := '
SELECT JSON_AGG(
JSON_BUILD_OBJECT(
''id'', id,
''case_number'', case_number,
''case_status'', case_status,
''job_title'', job_title,
''employer_name'', employer_name,
''wage_rate_of_pay_from'', wage_rate_of_pay_from,
''wage_rate_of_pay_to'', wage_rate_of_pay_to,
''received_date'', received_date,
''decision_date'', decision_date,
''employer_city'', employer_city,
''employer_state'', employer_state,
''worksite_city'', worksite_city,
''worksite_state'', worksite_state
) ORDER BY id DESC
)
FROM (
SELECT *
FROM h1b_applications ' || where_clause || '
ORDER BY id DESC
LIMIT ' || page_size || ' OFFSET ' || offset_count || '
) filtered_data';
EXECUTE query_text INTO result;
-- Build final response with pagination metadata
RETURN JSON_BUILD_OBJECT(
'data', COALESCE(result, '[]'::JSON),
'pagination', JSON_BUILD_OBJECT(
'totalRecords', total_count,
'totalPages', CEIL(total_count::NUMERIC / page_size),
'currentPage', page_number,
'pageSize', page_size,
'hasNextPage', (page_number * page_size) < total_count,
'hasPreviousPage', page_number > 1
)
);
EXCEPTION
WHEN OTHERS THEN
RETURN JSON_BUILD_OBJECT(
'error', true,
'message', 'Failed to retrieve filtered applications',
'code', 'FILTER_QUERY_ERROR',
'details', SQLERRM
);
END;
$;
-- Grant permissions
GRANT EXECUTE ON FUNCTION get_h1b_filtered_applications TO authenticated;
-- Test the function with various filter combinations
SELECT 'Testing get_h1b_filtered_applications - no filters' as test;
SELECT get_h1b_filtered_applications('{}', 5, 1);
SELECT 'Testing get_h1b_filtered_applications - employer filter' as test;
SELECT get_h1b_filtered_applications('{"employer": "Google"}', 5, 1);
SELECT 'Testing get_h1b_filtered_applications - salary range' as test;
SELECT get_h1b_filtered_applications('{"minSalary": 100000, "maxSalary": 200000}', 5, 1);
SELECT 'Testing get_h1b_filtered_applications - text search' as test;
SELECT get_h1b_filtered_applications('{"searchTerm": "software"}', 5, 1);
SELECT 'Filtering function created successfully!' as result;