File Coverage

blib/lib/JsonSQL/Schemas/select.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod 1 1 100.0
total 21 21 100.0


line stmt bran cond sub pod time code
1             # ABSTRACT: JsonSQL 'select' JSON schema.
2              
3              
4 2     2   1343 use strict;
  2         6  
  2         79  
5 2     2   14 use warnings;
  2         5  
  2         71  
6 2     2   40 use 5.014;
  2         8  
7              
8             package JsonSQL::Schemas::select;
9              
10             our $VERSION = '0.4'; # VERSION
11              
12 2     2   13 use base qw( JsonSQL::Schemas::Schema );
  2         5  
  2         474  
13              
14              
15              
16             my $jsonSchema = '
17             {
18             "title": "SQL Select Schema",
19             "id": "sqlSelectSchema",
20             "$schema": "http://json-schema.org/draft-04/schema#",
21             "description": "JSON schema to describe an SQL SELECT query",
22             "type": "object",
23             "properties": {
24             "defaultschema": {
25             "type": "string",
26             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
27             },
28             "distinct": {
29             "type": "string",
30             "enum": ["true", "false"]
31             },
32             "fields": {
33             "type": "array",
34             "items": {
35             "oneOf": [
36             {"$ref": "#/definitions/sqlAllFieldsObject"},
37             {"$ref": "#/definitions/sqlFromFieldObject"}
38             ]
39             },
40             "minItems": 1
41             },
42             "from": {
43             "type": "array",
44             "items": {"$ref": "#/definitions/sqlTableObject"},
45             "minItems": 1
46             },
47             "joins": {
48             "type": "array",
49             "items": {
50             "type": "object",
51             "properties": {
52             "jointype": {
53             "type": "string",
54             "enum": ["inner", "outerleft", "outerright", "outerfull", "cross"]
55             },
56             "from": {"$ref": "#/definitions/sqlTableObject"},
57             "to": {"$ref": "#/definitions/sqlTableObject"},
58             "on": {
59             "type": "object",
60             "patternProperties": {
61             "^eq$|^ne$|^gt$|^ge$|^lt$|^le$": {
62             "type": "object",
63             "properties": {
64             "field": {"$ref": "#/definitions/sqlWhereFieldObject"},
65             "value": {"$ref": "#/definitions/sqlWhereFieldObject"}
66             },
67             "additionalProperties": false,
68             "required": ["field", "value"]
69             }
70             },
71             "additionalProperties": false,
72             "minProperties": 1,
73             "maxProperties": 1
74             }
75             },
76             "additionalProperties": false,
77             "required": ["jointype", "from", "to"]
78             },
79             "minItems": 1
80             },
81             "where": {"$ref": "#/definitions/conditionalOperator"},
82             "groupby": {
83             "type": "array",
84             "items": {"$ref": "#/definitions/sqlWhereFieldObject"},
85             "minItems": 1
86             },
87             "having": {"$ref": "#/definitions/conditionalOperator"},
88             "orderby": {
89             "type": "array",
90             "items": {
91             "type": "object",
92             "properties": {
93             "field": {"$ref": "#/definitions/sqlWhereFieldObject"},
94             "order": {
95             "type": "string",
96             "enum": ["ASC", "DESC"]
97             },
98             "nulls": {
99             "type": "string",
100             "enum": ["FIRST", "LAST"]
101             }
102             },
103             "additionalProperties": false
104             },
105             "minItems": 1
106             },
107             "limit": {
108             "type": "integer",
109             "minimum": 1
110             },
111             "offset": {
112             "type": "integer",
113             "minimum": 1
114             }
115             },
116             "additionalProperties": false,
117             "required": ["fields"],
118             "dependencies": {
119             "anyOf": [
120             {"fields": ["from"]},
121             {"fields": ["joins"]}
122             ]
123             },
124             "definitions": {
125             "sqlAllFieldsObject": {
126             "type": "object",
127             "properties": {
128             "schema": {
129             "type": "string",
130             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
131             },
132             "table": {
133             "type": "string",
134             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
135             },
136             "column": {
137             "type": "string",
138             "pattern": "^\\\\*$"
139             }
140             },
141             "additionalProperties": false,
142             "required": ["column"],
143             "dependencies": {"schema": ["table"]}
144             },
145             "sqlFromFieldObject": {
146             "type": "object",
147             "properties": {
148             "schema": {
149             "type": "string",
150             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
151             },
152             "table": {
153             "type": "string",
154             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
155             },
156             "column": {
157             "type": "string",
158             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
159             },
160             "alias": {
161             "type": "string",
162             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
163             }
164             },
165             "additionalProperties": false,
166             "required": ["column"],
167             "dependencies": {"schema": ["table"]}
168             },
169             "sqlWhereFieldObject": {
170             "type": "object",
171             "properties": {
172             "schema": {
173             "type": "string",
174             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
175             },
176             "table": {
177             "type": "string",
178             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
179             },
180             "column": {
181             "type": "string",
182             "pattern": "^[a-zA-Z_][a-zA-Z0-9_:]*$"
183             }
184             },
185             "additionalProperties": false,
186             "required": ["column"],
187             "dependencies": {"schema": ["table"]}
188             },
189             "sqlTableObject": {
190             "type": "object",
191             "properties": {
192             "schema": {
193             "type": "string",
194             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
195             },
196             "table": {
197             "type": "string",
198             "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
199             }
200             },
201             "additionalProperties": false,
202             "required": ["table"]
203             },
204             "conditionalOperator": {
205             "type": "object",
206             "patternProperties": {
207             "^eq$|^ne$|^gt$|^ge$|^lt$|^le$": {
208             "type": "object",
209             "properties": {
210             "field": {"$ref": "#/definitions/sqlWhereFieldObject"},
211             "value": {
212             "oneOf": [
213             {"$ref": "#/definitions/sqlWhereFieldObject"},
214             {"type": "string"},
215             {"type": "number"}
216             ]
217             }
218             },
219             "additionalProperties": false,
220             "required": ["field", "value"]
221             },
222             "^in$|^ni$": {
223             "type": "object",
224             "properties": {
225             "field": {"$ref": "#/definitions/sqlWhereFieldObject"},
226             "list": {
227             "type": "array",
228             "items": {"type": "string"},
229             "minItems": 2
230             }
231             },
232             "additionalProperties": false,
233             "required": ["field", "list"]
234             },
235             "^bt$|^nb$": {
236             "type": "object",
237             "properties": {
238             "field": {"$ref": "#/definitions/sqlWhereFieldObject"},
239             "minvalue": {
240             "oneOf": [
241             {"$ref": "#/definitions/sqlWhereFieldObject"},
242             {"type": "string"},
243             {"type": "number"}
244             ]
245             },
246             "maxvalue": {
247             "oneOf": [
248             {"$ref": "#/definitions/sqlWhereFieldObject"},
249             {"type": "string"},
250             {"type": "number"}
251             ]
252             }
253             },
254             "additionalProperties": false,
255             "required": ["field", "minvalue", "maxvalue"]
256             },
257             "^isnull$|^notnull$": {
258             "type": "object",
259             "properties": {
260             "field": {"$ref": "#/definitions/sqlWhereFieldObject"}
261             },
262             "additionalProperties": false,
263             "required": ["field"]
264             },
265             "^and$|^or$": {
266             "type": "array",
267             "items": {"$ref": "#/definitions/conditionalOperator"},
268             "minItems": 2
269             }
270             },
271             "additionalProperties": false,
272             "minProperties": 1,
273             "maxProperties": 1
274             }
275             }
276             }
277             ';
278              
279              
280              
281             sub new {
282 7     7 1 17 my $class = shift;
283            
284 7         38 my $self = $class->SUPER::new();
285              
286 7         28 $self->{_json} = $jsonSchema;
287            
288 7         20 return $self;
289             }
290              
291              
292             1;
293              
294             __END__
295              
296             =pod
297              
298             =encoding UTF-8
299              
300             =head1 NAME
301              
302             JsonSQL::Schemas::select - JsonSQL 'select' JSON schema.
303              
304             =head1 VERSION
305              
306             version 0.4
307              
308             =head1 SYNOPSIS
309              
310             This is a JSON schema describing an SQL SELECT statement. It tries to support most of the commonly used features, including JOINs.
311             You can instantiate this directly, but it is better to use the load_schema dispatcher from L<JsonSQL::Schemas::Schema>.
312              
313             To use this:
314              
315             my $schema = JsonSQL::Schemas::select->new;
316             if ( eval { $schema->is_error } ) {
317             return "Could not load JSON schema: $schema->{message}";
318             } else {
319             my $schemaObj = parse_json($schema->{_json});
320             ...
321             }
322              
323             For this to be useful, you will have to create a JSON::Validator object to validate parsed JSON strings, or just use L<JsonSQL::Validator>.
324              
325             =head1 ATTRIBUTES
326              
327             =head2 $jsonSchema
328              
329             The SELECT schema as a JSON string.
330              
331             =head1 METHODS
332              
333             =head2 Constructor new -> JsonSQL::Schemas::select
334              
335             Constructor method to return the $jsonSchema as a property of a new instance of this object.
336              
337             =head1 AUTHOR
338              
339             Chris Hoefler <bhoefler@draper.com>
340              
341             =head1 COPYRIGHT AND LICENSE
342              
343             This software is copyright (c) 2017 by Chris Hoefler.
344              
345             This is free software; you can redistribute it and/or modify it under
346             the same terms as the Perl 5 programming language system itself.
347              
348             =cut