UNPKG

22.3 kBJavaScriptView Raw
1/**
2* FoxHound Query Generation Library
3*
4* @license MIT
5*
6* @author Steven Velozo <steven@velozo.com>
7* @module FoxHound
8*/
9
10// We use Underscore.js for utility
11var libUnderscore = require('underscore');
12
13// Load our base parameters skeleton object
14var baseParameters = require('./Parameters.js');
15
16/**
17* FoxHound Query Generation Library Main Class
18*
19* @class FoxHound
20* @constructor
21*/
22var FoxHound = function()
23{
24 function createNew(pFable, pFromParameters)
25 {
26 // If a valid Fable object isn't passed in, return a constructor
27 if ((typeof(pFable) !== 'object') || (!pFable.hasOwnProperty('fable')))
28 {
29 return {new: createNew};
30 }
31
32 var _Fable = pFable;
33
34 // The default parameters config object, used as a template for all new
35 // queries created from this query.
36 var _DefaultParameters = (typeof(pFromParameters) === 'undefined') ? {} : pFromParameters;
37
38 // The parameters config object for the current query. This is the only
39 // piece of internal state that is important to operation.
40 var _Parameters = false;
41
42 // The unique identifier for a query
43 var _UUID = _Fable.getUUID();
44
45 // The log level, for debugging chattiness.
46 var _LogLevel = 0;
47
48 // The dialect to use when generating queries
49 var _Dialect = false;
50
51 /**
52 * Clone the current FoxHound Query into a new Query object, copying all
53 * parameters as the new default. Clone also copies the log level.
54 *
55 * @method clone
56 * @return {Object} Returns a cloned Query. This is still chainable.
57 */
58 var clone = function()
59 {
60 var tmpFoxHound = createNew(_Fable, baseParameters)
61 .setScope(_Parameters.scope)
62 .setBegin(_Parameters.begin)
63 .setCap(_Parameters.cap);
64
65 // Schema is the only part of a query that carries forward.
66 tmpFoxHound.query.schema = _Parameters.query.schema;
67
68 if (_Parameters.dataElements)
69 {
70 tmpFoxHound.parameters.dataElements = _Parameters.dataElements.slice(); // Copy the array of dataElements
71 }
72 if (_Parameters.sort)
73 {
74 tmpFoxHound.parameters.sort = _Parameters.sort.slice(); // Copy the sort array.
75 // TODO: Fix the side affect nature of these being objects in the array .. they are technically clones of the previous.
76 }
77 if (_Parameters.filter)
78 {
79 tmpFoxHound.parameters.filter = _Parameters.filter.slice(); // Copy the filter array.
80 // TODO: Fix the side affect nature of these being objects in the array .. they are technically clones of the previous.
81 }
82
83 return tmpFoxHound;
84 };
85
86
87 /**
88 * Reset the parameters of the FoxHound Query to the Default. Default
89 * parameters were set during object construction.
90 *
91 * @method resetParameters
92 * @return {Object} Returns the current Query for chaining.
93 */
94 var resetParameters = function()
95 {
96 _Parameters = libUnderscore.extend({}, baseParameters, _DefaultParameters);
97 _Parameters.query = ({
98 disableAutoIdentity: false,
99 disableAutoDateStamp: false,
100 disableAutoUserStamp: false,
101 disableDeleteTracking: false,
102 body: false,
103 schema: false, // The schema to intersect with our records
104 IDUser: 0, // The user to stamp into records
105 UUID: _Fable.getUUID(), // A UUID for this record
106 records: false, // The records to be created or changed
107 parameters: {}
108 });
109
110 _Parameters.result = ({
111 executed: false, // True once we've run a query.
112 value: false, // The return value of the last query run
113 error: false // The error message of the last run query
114 });
115
116 return this;
117 };
118 resetParameters();
119
120 /**
121 * Reset the parameters of the FoxHound Query to the Default. Default
122 * parameters were set during object construction.
123 *
124 * @method mergeParameters
125 * @param {Object} pFromParameters A Parameters Object to merge from
126 * @return {Object} Returns the current Query for chaining.
127 */
128 var mergeParameters = function(pFromParameters)
129 {
130 _Parameters = libUnderscore.extend({}, _Parameters, pFromParameters);
131 return this;
132 };
133
134
135 /**
136 * Set the the Logging level.
137 *
138 * The log levels are:
139 * 0 - Don't log anything
140 * 1 - Log queries
141 * 2 - Log queries and non-parameterized queries
142 * 3 - Log everything
143 *
144 * @method setLogLevel
145 * @param {Number} pLogLevel The log level for our object
146 * @return {Object} Returns the current Query for chaining.
147 */
148 var setLogLevel = function(pLogLevel)
149 {
150 var tmpLogLevel = 0;
151
152 if (typeof(pLogLevel) === 'number' && (pLogLevel % 1) === 0)
153 {
154 tmpLogLevel = pLogLevel;
155 }
156
157 _LogLevel = tmpLogLevel;
158
159 return this;
160 };
161
162
163 /**
164 * Set the Scope for the Query. *Scope* is the source for the data being
165 * pulled. In TSQL this would be the _table_, whereas in MongoDB this
166 * would be the _collection_.
167 *
168 * A scope can be either a string, or an array (for JOINs and such).
169 *
170 * @method setScope
171 * @param {String} pScope A Scope for the Query.
172 * @return {Object} Returns the current Query for chaining.
173 */
174 var setScope = function(pScope)
175 {
176 var tmpScope = false;
177
178 if (typeof(pScope) === 'string')
179 {
180 tmpScope = pScope;
181 }
182 else if (pScope !== false)
183 {
184 _Fable.log.error('Scope set failed. You must pass in a string or array.', {queryUUID:_UUID, parameters:_Parameters, invalidScope:pScope});
185 }
186
187 _Parameters.scope = tmpScope;
188
189 if (_LogLevel > 2)
190 {
191 _Fable.log.info('Scope set: '+tmpScope, {queryUUID:_UUID, parameters:_Parameters});
192 }
193
194 return this;
195 };
196
197
198 /**
199 * Set the Data Elements for the Query. *Data Elements* are the fields
200 * being pulled by the query. In TSQL this would be the _columns_,
201 * whereas in MongoDB this would be the _fields_.
202 *
203 * The passed values can be either a string, or an array.
204 *
205 * @method setDataElements
206 * @param {String} pDataElements The Data Element(s) for the Query.
207 * @return {Object} Returns the current Query for chaining.
208 */
209 var setDataElements = function(pDataElements)
210 {
211 var tmpDataElements = false;
212
213 if (Array.isArray(pDataElements))
214 {
215 // TODO: Check each entry of the array are all strings
216 tmpDataElements = pDataElements;
217 }
218 if (typeof(pDataElements) === 'string')
219 {
220 tmpDataElements = [pDataElements];
221 }
222
223 _Parameters.dataElements = tmpDataElements;
224
225 if (_LogLevel > 2)
226 {
227 _Fable.log.info('Data Elements set', {queryUUID:_UUID, parameters:_Parameters});
228 }
229
230 return this;
231 };
232
233
234 /**
235 * Set the sort data element
236 *
237 * The passed values can be either a string, an object or an array of objects.
238 *
239 * The Sort object has two values:
240 * {Column:'Birthday', Direction:'Ascending'}
241 *
242 * @method setSort
243 * @param {String} pSort The sort criteria(s) for the Query.
244 * @return {Object} Returns the current Query for chaining.
245 */
246 var setSort = function(pSort)
247 {
248 var tmpSort = false;
249
250 if (Array.isArray(pSort))
251 {
252 // TODO: Check each entry of the array are all conformant sort objects
253 tmpSort = pSort;
254 }
255 else if (typeof(pSort) === 'string')
256 {
257 // Default to ascending
258 tmpSort = [{Column:pSort, Direction:'Ascending'}];
259 }
260 else if (typeof(pSort) === 'object')
261 {
262 // TODO: Check that this sort entry conforms to a sort entry
263 tmpSort = [pSort];
264 }
265
266 _Parameters.sort = tmpSort;
267
268 if (_LogLevel > 2)
269 {
270 _Fable.log.info('Sort set', {queryUUID:_UUID, parameters:_Parameters});
271 }
272
273 return this;
274 };
275
276 /**
277 * Set the join data element
278 *
279 * The passed values can be either an object or an array of objects.
280 *
281 * The join object has four values:
282 * {Type:'INNER JOIN', Table:'Test', From:'Test.ID', To:'Scope.IDItem'}
283 *
284 * @method setJoin
285 * @param {Object} pJoin The join criteria(s) for the Query.
286 * @return {Object} Returns the current Query for chaining.
287 */
288 var setJoin = function(pJoin)
289 {
290 _Parameters.join = [];
291
292 if (Array.isArray(pJoin))
293 {
294 pJoin.forEach(function(join)
295 {
296 addJoin(join.Table, join.From, join.To, join.Type);
297 });
298 }
299 else if (typeof(pJoin) === 'object')
300 {
301 addJoin(pJoin.Table, pJoin.From, pJoin.To, pJoin.Type);
302 }
303
304 return this;
305 }
306
307
308 /**
309 * Add a sort data element
310 *
311 * The passed values can be either a string, an object or an array of objects.
312 *
313 * The Sort object has two values:
314 * {Column:'Birthday', Direction:'Ascending'}
315 *
316 * @method setSort
317 * @param {String} pSort The sort criteria to add to the Query.
318 * @return {Object} Returns the current Query for chaining.
319 */
320 var addSort = function(pSort)
321 {
322 var tmpSort = false;
323
324 if (typeof(pSort) === 'string')
325 {
326 // Default to ascending
327 tmpSort = {Column:pSort, Direction:'Ascending'};
328 }
329 if (typeof(pSort) === 'object')
330 {
331 // TODO: Check that this sort entry conforms to a sort entry
332 tmpSort = pSort;
333 }
334
335 if (!_Parameters.sort)
336 {
337 _Parameters.sort = [];
338 }
339
340 _Parameters.sort.push(tmpSort);
341
342 if (_LogLevel > 2)
343 {
344 _Fable.log.info('Sort set', {queryUUID:_UUID, parameters:_Parameters});
345 }
346
347 return this;
348 };
349
350
351 /**
352 * Set the the Begin index for the Query. *Begin* is the index at which
353 * a query should start returning rows. In TSQL this would be the n
354 * parameter of ```LIMIT 1,n```, whereas in MongoDB this would be the
355 * n in ```skip(n)```.
356 *
357 * The passed value must be an Integer >= 0.
358 *
359 * @method setBegin
360 * @param {Number} pBeginAmount The index to begin returning Query data.
361 * @return {Object} Returns the current Query for chaining.
362 */
363 var setBegin = function(pBeginAmount)
364 {
365 var tmpBegin = false;
366
367 // Test if it is an integer > -1
368 // http://jsperf.com/numbers-and-integers
369 if (typeof(pBeginAmount) === 'number' && (pBeginAmount % 1) === 0 && pBeginAmount >= 0)
370 {
371 tmpBegin = pBeginAmount;
372 }
373 else if (pBeginAmount !== false)
374 {
375 _Fable.log.error('Begin set failed; non-positive or non-numeric argument.', {queryUUID:_UUID, parameters:_Parameters, invalidBeginAmount:pBeginAmount});
376 }
377
378 _Parameters.begin = tmpBegin;
379
380 if (_LogLevel > 2)
381 {
382 _Fable.log.info('Begin set: '+pBeginAmount, {queryUUID:_UUID, parameters:_Parameters});
383 }
384
385 return this;
386 };
387
388
389 /**
390 * Set the the Cap for the Query. *Cap* is the maximum number of records
391 * a Query should return in a set. In TSQL this would be the n
392 * parameter of ```LIMIT n```, whereas in MongoDB this would be the
393 * n in ```limit(n)```.
394 *
395 * The passed value must be an Integer >= 0.
396 *
397 * @method setCap
398 * @param {Number} pCapAmount The maximum records for the Query set.
399 * @return {Object} Returns the current Query for chaining.
400 */
401 var setCap = function(pCapAmount)
402 {
403 var tmpCapAmount = false;
404
405 if (typeof(pCapAmount) === 'number' && (pCapAmount % 1) === 0 && pCapAmount >= 0)
406 {
407 tmpCapAmount = pCapAmount;
408 }
409 else if (pCapAmount !== false)
410 {
411 _Fable.log.error('Cap set failed; non-positive or non-numeric argument.', {queryUUID:_UUID, parameters:_Parameters, invalidCapAmount:pCapAmount});
412 }
413
414
415 _Parameters.cap = tmpCapAmount;
416
417 if (_LogLevel > 2)
418 {
419 _Fable.log.info('Cap set to: '+tmpCapAmount, {queryUUID:_UUID, parameters:_Parameters});
420 }
421
422 return this;
423 };
424
425
426 /**
427 * Set the filter expression
428 *
429 * The passed values can be either an object or an array of objects.
430 *
431 * The Filter object has a minimum of two values (which expands to the following):
432 * {Column:'Name', Value:'John'}
433 * {Column:'Name', Operator:'EQ', Value:'John', Connector:'And', Parameter:'Name'}
434 *
435 * @method setFilter
436 * @param {String} pFilter The filter(s) for the Query.
437 * @return {Object} Returns the current Query for chaining.
438 */
439 var setFilter = function(pFilter)
440 {
441 var tmpFilter = false;
442
443 if (Array.isArray(pFilter))
444 {
445 // TODO: Check each entry of the array are all conformant Filter objects
446 tmpFilter = pFilter;
447 }
448 else if (typeof(pFilter) === 'object')
449 {
450 // TODO: Check that this Filter entry conforms to a Filter entry
451 tmpFilter = [pFilter];
452 }
453
454 _Parameters.filter = tmpFilter;
455
456 if (_LogLevel > 2)
457 {
458 _Fable.log.info('Filter set', {queryUUID:_UUID, parameters:_Parameters});
459 }
460
461 return this;
462 };
463
464
465
466 /**
467 * Add a filter expression
468 *
469 * {Column:'Name', Operator:'EQ', Value:'John', Connector:'And', Parameter:'Name'}
470 *
471 * @method addFilter
472 * @return {Object} Returns the current Query for chaining.
473 */
474 var addFilter = function(pColumn, pValue, pOperator, pConnector, pParameter)
475 {
476 if (typeof(pColumn) !== 'string')
477 {
478 _Fable.log.warn('Tried to add an invalid query filter column', {queryUUID:_UUID, parameters:_Parameters});
479 return this;
480 }
481 if (typeof(pValue) === 'undefined')
482 {
483 _Fable.log.warn('Tried to add an invalid query filter value', {queryUUID:_UUID, parameters:_Parameters, invalidColumn:pColumn});
484 return this;
485 }
486 var tmpOperator = (typeof(pOperator) === 'undefined') ? '=' : pOperator;
487 var tmpConnector = (typeof(pConnector) === 'undefined') ? 'AND' : pConnector;
488 var tmpParameter = (typeof(pParameter) === 'undefined') ? pColumn : pParameter;
489
490 //support table.field notation (mysql2 requires this)
491 tmpParameter = tmpParameter.replace('.', '_');
492
493 var tmpFilter = (
494 {
495 Column: pColumn,
496 Operator: tmpOperator,
497 Value: pValue,
498 Connector: tmpConnector,
499 Parameter: tmpParameter
500 });
501
502 if (!Array.isArray(_Parameters.filter))
503 {
504 _Parameters.filter = [tmpFilter];
505 }
506 else
507 {
508 _Parameters.filter.push(tmpFilter);
509 }
510
511 if (_LogLevel > 2)
512 {
513 _Fable.log.info('Added a filter', {queryUUID:_UUID, parameters:_Parameters, newFilter:tmpFilter});
514 }
515
516 return this;
517 };
518
519 /**
520 * Add a join expression
521 *
522 * {Type:'INNER JOIN', Table:'Test', From:'Test.ID', To:'Scope.IDItem'}
523 *
524 * @method addJoin
525 * @return {Object} Returns the current Query for chaining.
526 */
527 var addJoin = function(pTable, pFrom, pTo, pType = 'INNER JOIN')
528 {
529 if (typeof(pTable) !== 'string')
530 {
531 _Fable.log.warn('Tried to add an invalid query join table', {queryUUID:_UUID, parameters:_Parameters});
532 return this;
533 }
534 if (typeof(pFrom) === 'undefined' || typeof(pTo) === 'undefined')
535 {
536 _Fable.log.warn('Tried to add an invalid query join field', {queryUUID:_UUID, parameters:_Parameters});
537 return this;
538 }
539 //sanity check the join fields
540 if (pFrom.indexOf(pTable)!=0)
541 {
542 _Fable.log.warn('Tried to add an invalid query join field, join must come FROM the join table!', {queryUUID:_UUID, parameters:_Parameters, invalidField:pFrom});
543 return this;
544 }
545 if (pTo.indexOf('.')<=0)
546 {
547 _Fable.log.warn('Tried to add an invalid query join field, join must go TO a field on another table ([table].[field])!', {queryUUID:_UUID, parameters:_Parameters, invalidField:pTo});
548 return this;
549 }
550
551 var tmpJoin = (
552 {
553 Type: pType,
554 Table: pTable,
555 From: pFrom,
556 To: pTo
557 });
558
559 if (!Array.isArray(_Parameters.join))
560 {
561 _Parameters.join = [tmpJoin];
562 }
563 else
564 {
565 _Parameters.join.push(tmpJoin);
566 }
567
568 if (_LogLevel > 2)
569 {
570 _Fable.log.info('Added a join', {queryUUID:_UUID, parameters:_Parameters, newFilter:tmpFilter});
571 }
572
573 return this;
574 };
575
576
577
578 /**
579 * Add a record (for UPDATE and INSERT)
580 *
581 *
582 * @method addRecord
583 * @param {Object} pRecord The record to add.
584 * @return {Object} Returns the current Query for chaining.
585 */
586 var addRecord = function(pRecord)
587 {
588 if (typeof(pRecord) !== 'object')
589 {
590 _Fable.log.warn('Tried to add an invalid record to the query -- records must be an object', {queryUUID:_UUID, parameters:_Parameters});
591 return this;
592 }
593
594 if (!Array.isArray(_Parameters.query.records))
595 {
596 _Parameters.query.records = [pRecord];
597 }
598 else
599 {
600 _Parameters.query.records.push(pRecord);
601 }
602
603 if (_LogLevel > 2)
604 {
605 _Fable.log.info('Added a record to the query', {queryUUID:_UUID, parameters:_Parameters, newRecord:pRecord});
606 }
607
608 return this;
609 };
610
611
612
613 /**
614 * Set the Dialect for Query generation.
615 *
616 * This function expects a string, case sensitive, which matches both the
617 * folder and filename
618 *
619 * @method setDialect
620 * @param {String} pDialectName The dialect for query generation.
621 * @return {Object} Returns the current Query for chaining.
622 */
623 var setDialect = function(pDialectName)
624 {
625 if (typeof(pDialectName) !== 'string')
626 {
627 _Fable.log.warn('Dialect set to English - invalid name', {queryUUID:_UUID, parameters:_Parameters, invalidDialect:pDialectName});
628 return setDialect('English');
629 }
630
631 var tmpDialectModuleFile = './dialects/'+pDialectName+'/FoxHound-Dialect-'+pDialectName+'.js';
632
633 try
634 {
635 var tmpDialectModule = require(tmpDialectModuleFile);
636 _Dialect = tmpDialectModule;
637 if (_LogLevel > 2)
638 {
639 _Fable.log.info('Dialog set to: '+pDialectName, {queryUUID:_UUID, parameters:_Parameters, dialectModuleFile:tmpDialectModuleFile});
640 }
641 }
642 catch (pError)
643 {
644 _Fable.log.error('Dialect not set - require load problem', {queryUUID:_UUID, parameters:_Parameters, dialectModuleFile:tmpDialectModuleFile, invalidDialect:pDialectName, error:pError});
645 setDialect('English');
646 }
647
648 return this;
649 };
650
651 /**
652 * User to use for this query
653 *
654 * @method setIDUser
655 */
656 var setIDUser = function(pIDUser)
657 {
658
659 var tmpUserID = 0;
660
661 if (typeof(pIDUser) === 'number' && (pIDUser % 1) === 0 && pIDUser >= 0)
662 {
663 tmpUserID = pIDUser;
664 }
665 else if (pIDUser !== false)
666 {
667 _Fable.log.error('User set failed; non-positive or non-numeric argument.', {queryUUID:_UUID, parameters:_Parameters, invalidIDUser:pIDUser});
668 }
669
670
671 _Parameters.userID = tmpUserID;
672 _Parameters.query.IDUser = tmpUserID;
673
674 if (_LogLevel > 2)
675 {
676 _Fable.log.info('IDUser set to: '+tmpUserID, {queryUUID:_UUID, parameters:_Parameters});
677 }
678
679 return this;
680 };
681
682 /**
683 * Flag to disable auto identity
684 *
685 * @method setDisableAutoIdentity
686 */
687 var setDisableAutoIdentity = function(pFlag)
688 {
689 _Parameters.query.disableAutoIdentity = pFlag;
690
691 return this; //chainable
692 };
693
694 /**
695 * Flag to disable auto datestamp
696 *
697 * @method setDisableAutoDateStamp
698 */
699 var setDisableAutoDateStamp = function(pFlag)
700 {
701 _Parameters.query.disableAutoDateStamp = pFlag;
702
703 return this; //chainable
704 };
705
706 /**
707 * Flag to disable auto userstamp
708 *
709 * @method setDisableAutoUserStamp
710 */
711 var setDisableAutoUserStamp = function(pFlag)
712 {
713 _Parameters.query.disableAutoUserStamp = pFlag;
714
715 return this; //chainable
716 };
717
718 /**
719 * Flag to disable delete tracking
720 *
721 * @method setDisableDeleteTracking
722 */
723 var setDisableDeleteTracking = function(pFlag)
724 {
725 _Parameters.query.disableDeleteTracking = pFlag;
726
727 return this; //chainable
728 };
729
730 /**
731 * Check that a valid Dialect has been set
732 *
733 * If there has not been a dialect set, it defaults to English.
734 * TODO: Have the json configuration define a "default" dialect.
735 *
736 * @method checkDialect
737 */
738 var checkDialect = function()
739 {
740 if (_Dialect === false)
741 {
742 setDialect('English');
743 }
744 };
745
746
747 var buildCreateQuery = function()
748 {
749 checkDialect();
750 _Parameters.query.body = _Dialect.Create(_Parameters);
751 return this;
752 };
753
754 var buildReadQuery = function()
755 {
756 checkDialect();
757 _Parameters.query.body = _Dialect.Read(_Parameters);
758 return this;
759 };
760
761 var buildUpdateQuery = function()
762 {
763 checkDialect();
764 _Parameters.query.body = _Dialect.Update(_Parameters);
765 return this;
766 };
767
768 var buildDeleteQuery = function()
769 {
770 checkDialect();
771 _Parameters.query.body = _Dialect.Delete(_Parameters);
772 return this;
773 };
774
775 var buildCountQuery = function()
776 {
777 checkDialect();
778 _Parameters.query.body = _Dialect.Count(_Parameters);
779 return this;
780 };
781
782 /**
783 * Container Object for our Factory Pattern
784 */
785 var tmpNewFoxHoundObject = (
786 {
787 resetParameters: resetParameters,
788 mergeParameters: mergeParameters,
789
790 setLogLevel: setLogLevel,
791
792 setScope: setScope,
793 setIDUser: setIDUser,
794 setDataElements: setDataElements,
795 setBegin: setBegin,
796 setCap: setCap,
797 setFilter: setFilter,
798 addFilter: addFilter,
799 setSort: setSort,
800 addSort: addSort,
801 setJoin: setJoin,
802 addJoin, addJoin,
803
804 addRecord: addRecord,
805 setDisableAutoIdentity: setDisableAutoIdentity,
806 setDisableAutoDateStamp: setDisableAutoDateStamp,
807 setDisableAutoUserStamp: setDisableAutoUserStamp,
808 setDisableDeleteTracking: setDisableDeleteTracking,
809
810 setDialect: setDialect,
811
812 buildCreateQuery: buildCreateQuery,
813 buildReadQuery: buildReadQuery,
814 buildUpdateQuery: buildUpdateQuery,
815 buildDeleteQuery: buildDeleteQuery,
816 buildCountQuery: buildCountQuery,
817
818 clone: clone,
819 new: createNew
820 });
821
822 /**
823 * Query
824 *
825 * @property query
826 * @type Object
827 */
828 Object.defineProperty(tmpNewFoxHoundObject, 'query',
829 {
830 get: function() { return _Parameters.query; },
831 set: function(pQuery) { _Parameters.query = pQuery; },
832 enumerable: true
833 });
834
835 /**
836 * Result
837 *
838 * @property result
839 * @type Object
840 */
841 Object.defineProperty(tmpNewFoxHoundObject, 'result',
842 {
843 get: function() { return _Parameters.result; },
844 set: function(pResult) { _Parameters.result = pResult; },
845 enumerable: true
846 });
847
848 /**
849 * Query Parameters
850 *
851 * @property parameters
852 * @type Object
853 */
854 Object.defineProperty(tmpNewFoxHoundObject, 'parameters',
855 {
856 get: function() { return _Parameters; },
857 set: function(pParameters) { _Parameters = pParameters; },
858 enumerable: true
859 });
860
861 /**
862 * Dialect
863 *
864 * @property dialect
865 * @type Object
866 */
867 Object.defineProperty(tmpNewFoxHoundObject, 'dialect',
868 {
869 get: function() { return _Dialect; },
870 enumerable: true
871 });
872
873 /**
874 * Universally Unique Identifier
875 *
876 * @property uuid
877 * @type String
878 */
879 Object.defineProperty(tmpNewFoxHoundObject, 'uuid',
880 {
881 get: function() { return _UUID; },
882 enumerable: true
883 });
884
885 /**
886 * Log Level
887 *
888 * @property logLevel
889 * @type Integer
890 */
891 Object.defineProperty(tmpNewFoxHoundObject, 'logLevel',
892 {
893 get: function() { return _LogLevel; },
894 enumerable: true
895 });
896
897 return tmpNewFoxHoundObject;
898 }
899
900 return createNew();
901};
902
903module.exports = new FoxHound();