UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

6 lines (5 loc) • 15 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.32/esri/copyright.txt for details. */ import has from"../has.js";import{isAggregate as e,aggregateFunction as t}from"./AggregateFunctions.js";import{DateOnly as r}from"./DateOnly.js";import{SqlError as a,SqlErrorCodes as s}from"./errorSupport.js";import{sqlCalculateFunction as i}from"./sqlArithmeticUtils.js";import{sqlCompare as n,isDateOrTimeValue as o}from"./sqlCompareUtils.js";import{isDateTime as u,isTimestampOffset as l,isTimeOnly as c,isDateOnly as h,parseTime as p,parseTimestamp as m,parseDate as d,convertToExecutingTimeZone as f}from"./sqlDateParsingUtils.js";import{SqlInterval as v}from"./SqlInterval.js";import{SqlTimeStampOffset as N}from"./SqlTimestampOffset.js";import{evaluateFunction as g,isStandardized as S}from"./StandardizedFunctions.js";import{TimeOnly as T}from"./TimeOnly.js";import{WhereGrammar as y,visitAll as _}from"./WhereGrammar.js";import{isDate as J}from"../../support/guards.js";import{DateTime as w,FixedOffsetZone as I}from"luxon";const O=new Set(["current_timestamp","current_date","current_time"]);class F{static makeBool(e){return Z(e)}static featureValue(e,t,r,a){return R(e,t,r,a)}static equalsNull(e){return null===e}static applyLike(e,t,r){return L(e,t,r)}static ensureArray(e){return x(e)}static applyIn(e,t,r){return U(e,t)}static currentTimestamp(e){return f(new Date,e)}static currentDate(e){return r.fromNow(e)}static currentTime(e){const t=f(new Date,e);return T.fromDateTime(t)}static makeSqlInterval(e,t,r){return v.createFromValueAndQualifier(e,t,r)}static convertInterval(e){return v.isInterval(e)?e.valueInMilliseconds():e}static compare(e,t,r,a){return n(t,r,e)}static calculate(e,t,r,a){return i(e,t,r,a)}static evaluateTime(e){return p(e)}static evaluateTimestamp(e,t,r){return m(e,t,r)}static evaluateDate(e,t){return d(e,t)}static evaluateFunction(e,t,r){return g(e,t,r)}static lookup(e,t){const r=t[e];return void 0===r?null:r}static between(e,t,r){return null==e||null==t[0]||null==t[1]?null:n(e,t[0],">=")&&n(e,t[1],"<=")}static notbetween(e,t,r){return null==e||null==t[0]||null==t[1]?null:n(e,t[0],"<")||n(e,t[1],">")}static ternaryNot(e){return b(e)}static ternaryAnd(e,t){return A(e,t)}static ternaryOr(e,t){return E(e,t)}}class D{constructor(e,t,r="UTC",a=null){this.fieldsIndex=t,this.timeZone=r,this.currentUser=a,this.parameters={},this._hasDateFunctions=void 0,this.parseTree=y.parse(e);const{isStandardized:s,isAggregate:i,currentUserRequired:n,referencedFieldNames:o}=this._extractExpressionInfo(t);this._referencedFieldNames=o,this.isStandardized=s,this.isAggregate=i,this.currentUserRequired=n}static convertValueToStorageFormat(e,t=null){if(null===t)return J(e)?e.getTime():u(e)?e.toMillis():l(e)?e.toStorageFormat():c(e)?e.toStorageString():h(e)?e.toStorageFormat():e;switch(t){case"date":return J(e)?e.getTime():u(e)?e.toMillis():l(e)?e.toMilliseconds():h(e)?e.toNumber():e;case"date-only":return J(e)?r.fromDateJS(e).toString():l(e)?r.fromSqlTimeStampOffset(e).toString():u(e)?r.fromDateTime(e).toString():e;case"time-only":return J(e)?T.fromDateJS(e).toStorageString():u(e)?T.fromDateTime(e).toStorageString():l(e)?T.fromSqlTimeStampOffset(e).toStorageString():c(e)?e.toStorageString():e;case"timestamp-offset":if(J(e))return N.fromJSDate(e).toStorageFormat();if(u(e))return N.fromDateTime(e).toStorageFormat();if(l(e))return e.toStorageFormat()}return e}static create(e,t={}){return new D(e,t.fieldsIndex,t.timeZone??void 0,t.currentUser)}get fieldNames(){return this._referencedFieldNames}testSet(e,t=C,r=this.currentUser){return!!this._evaluateNode(this.parseTree,null,t,e,r)}calculateValue(e,t=C,r=this.currentUser){const a=this._evaluateNode(this.parseTree,e,t,null,r);return v.isInterval(a)?a.valueInMilliseconds()/864e5:a}calculateValueCompiled(e,t=C,r=this.currentUser){return null!=this.parseTree._compiledVersion?this.parseTree._compiledVersion(e,this.parameters,t,this.fieldsIndex,this.timeZone,r??null):has("esri-csp-restrictions")?this.calculateValue(e,t):(this._compileMe(),this.parseTree._compiledVersion(e,this.parameters,t,this.fieldsIndex,this.timeZone,r??null))}testFeature(e,t=C,r=this.currentUser){return!!this._evaluateNode(this.parseTree,e,t,null,r)}testFeatureCompiled(e,t=C,r=this.currentUser){return null!=this.parseTree._compiledVersion?!!this.parseTree._compiledVersion(e,this.parameters,t,this.fieldsIndex,this.timeZone,r??null):has("esri-csp-restrictions")?this.testFeature(e,t):(this._compileMe(),!!this.parseTree._compiledVersion(e,this.parameters,t,this.fieldsIndex,this.timeZone,r??null))}get hasDateFunctions(){return null!=this._hasDateFunctions||(this._hasDateFunctions=!1,_(this.parseTree,(e=>{"current-time"===e.type?this._hasDateFunctions=!0:"function"===e.type&&(this._hasDateFunctions=this._hasDateFunctions||O.has(e.name.toLowerCase()))}))),this._hasDateFunctions}getFunctions(){const e=new Set;return _(this.parseTree,(t=>{"function"===t.type&&e.add(t.name.toLowerCase())})),Array.from(e)}getExpressions(){const e=new Map;return _(this.parseTree,(t=>{if("function"===t.type){const r=t.name.toLowerCase(),a=t.args.value[0];if("column-reference"===a.type){const t=a.column,s=`${r}-${t}`;e.has(s)||e.set(s,{aggregateType:r,field:t})}}})),[...e.values()]}getVariables(){const e=new Set;return _(this.parseTree,(t=>{"parameter"===t.type&&e.add(t.value.toLowerCase())})),Array.from(e)}_compileMe(){const e="return this.convertInterval("+this.evaluateNodeToJavaScript(this.parseTree)+")";this.parseTree._compiledVersion=new Function("feature","lookups","attributeAdapter","fieldsIndex","timeZone","currentUser",e).bind(F)}_extractExpressionInfo(t){const r=[],a=new Set;let s=!0,i=!1,n=!1;return _(this.parseTree,(o=>{switch(o.type){case"column-reference":{const e=t?.get(o.column);let s,i;e?s=i=e.name??"":(i=o.column,s=i.toLowerCase()),a.has(s)||(a.add(s),r.push(i)),o.column=i;break}case"current-user":n=!0;break;case"function":{const{name:t,args:r}=o,a=r.value.length;s&&(s=S(t,a)),!1===i&&(i=e(t,a));break}}})),{referencedFieldNames:Array.from(r),isStandardized:s,isAggregate:i,currentUserRequired:n}}evaluateNodeToJavaScript(e){switch(e.type){case"interval":return"this.makeSqlInterval("+this.evaluateNodeToJavaScript(e.value)+", "+JSON.stringify(e.qualifier)+","+JSON.stringify(e.op)+")";case"case-expression":{let t="";if("simple"===e.format){const r=this.evaluateNodeToJavaScript(e.operand);t="( ";for(let a=0;a<e.clauses.length;a++)t+=" (this.compare('=',"+r+","+this.evaluateNodeToJavaScript(e.clauses[a].operand)+") ? ("+this.evaluateNodeToJavaScript(e.clauses[a].value)+") : ";null!==e.else?t+=this.evaluateNodeToJavaScript(e.else):t+="null",t+=" )"}else{t="( ";for(let r=0;r<e.clauses.length;r++)t+=" this.makeBool("+this.evaluateNodeToJavaScript(e.clauses[r].operand)+")===true ? ("+this.evaluateNodeToJavaScript(e.clauses[r].value)+") : ";null!==e.else?t+=this.evaluateNodeToJavaScript(e.else):t+="null",t+=" )"}return t}case"parameter":return"this.lookup("+JSON.stringify(e.value.toLowerCase())+",lookups)";case"expression-list":{let t="[";for(const r of e.value)"["!==t&&(t+=","),t+=this.evaluateNodeToJavaScript(r);return t+="]",t}case"unary-expression":return"this.ternaryNot("+this.evaluateNodeToJavaScript(e.expr)+")";case"binary-expression":switch(e.operator){case"AND":return"this.ternaryAnd("+this.evaluateNodeToJavaScript(e.left)+","+this.evaluateNodeToJavaScript(e.right)+" )";case"OR":return"this.ternaryOr("+this.evaluateNodeToJavaScript(e.left)+","+this.evaluateNodeToJavaScript(e.right)+" )";case"IS":if("null"!==e.right.type)throw new a(s.UnsupportedIsRhs);return"this.equalsNull("+this.evaluateNodeToJavaScript(e.left)+")";case"ISNOT":if("null"!==e.right.type)throw new a(s.UnsupportedIsRhs);return"(!(this.equalsNull("+this.evaluateNodeToJavaScript(e.left)+")))";case"IN":return"this.applyIn("+this.evaluateNodeToJavaScript(e.left)+",this.ensureArray("+this.evaluateNodeToJavaScript(e.right)+"), timeZone)";case"NOT IN":return"this.ternaryNot(this.applyIn("+this.evaluateNodeToJavaScript(e.left)+",this.ensureArray("+this.evaluateNodeToJavaScript(e.right)+"), timeZone))";case"BETWEEN":return"this.between("+this.evaluateNodeToJavaScript(e.left)+","+this.evaluateNodeToJavaScript(e.right)+", timeZone)";case"NOTBETWEEN":return"this.notbetween("+this.evaluateNodeToJavaScript(e.left)+","+this.evaluateNodeToJavaScript(e.right)+", timeZone)";case"LIKE":return"this.applyLike("+this.evaluateNodeToJavaScript(e.left)+","+this.evaluateNodeToJavaScript(e.right)+","+JSON.stringify(e.escape)+")";case"NOT LIKE":return"this.ternaryNot(this.applyLike("+this.evaluateNodeToJavaScript(e.left)+","+this.evaluateNodeToJavaScript(e.right)+","+JSON.stringify(e.escape)+"))";case"<>":case"<":case">":case">=":case"<=":case"=":return"this.compare("+JSON.stringify(e.operator)+","+this.evaluateNodeToJavaScript(e.left)+","+this.evaluateNodeToJavaScript(e.right)+", timeZone)";case"*":case"-":case"+":case"/":case"||":return"this.calculate("+JSON.stringify(e.operator)+","+this.evaluateNodeToJavaScript(e.left)+","+this.evaluateNodeToJavaScript(e.right)+", timeZone)";default:throw new a(s.UnsupportedOperator,{operator:e.operator})}case"null":case"boolean":case"string":case"number":return JSON.stringify(e.value);case"time":return"this.evaluateTime("+JSON.stringify(e.value)+")";case"date":return"this.evaluateDate("+JSON.stringify(e.value)+", 'unknown')";case"timestamp":return"this.evaluateTimestamp("+JSON.stringify(e.value)+", 'unknown')";case"current-time":return"date"===e.mode?"this.currentDate(timeZone)":"time"===e.mode?"this.currentTime(timeZone)":"this.currentTimestamp(timeZone)";case"current-user":return"currentUser";case"column-reference":return"this.featureValue(feature,"+JSON.stringify(e.column)+",fieldsIndex,attributeAdapter)";case"function":return"this.evaluateFunction("+JSON.stringify(e.name)+","+this.evaluateNodeToJavaScript(e.args)+", timeZone)"}throw new a(s.UnsupportedSyntax,{node:e.type})}_evaluateNode(r,o,u,l,c){let h;switch(r.type){case"interval":{const e=this._evaluateNode(r.value,o,u,l,c);return v.createFromValueAndQualifier(e,r.qualifier,r.op)}case"case-expression":if("simple"===r.format){const e=this._evaluateNode(r.operand,o,u,l,c);for(let t=0;t<r.clauses.length;t++)if(n(e,this._evaluateNode(r.clauses[t].operand,o,u,l,c),"=",this.timeZone))return this._evaluateNode(r.clauses[t].value,o,u,l,c);if(null!==r.else)return this._evaluateNode(r.else,o,u,l,c)}else{for(let e=0;e<r.clauses.length;e++)if(Z(this._evaluateNode(r.clauses[e].operand,o,u,l,c)))return this._evaluateNode(r.clauses[e].value,o,u,l,c);if(null!==r.else)return this._evaluateNode(r.else,o,u,l,c)}return null;case"parameter":return h=this.parameters[r.value.toLowerCase()],J(h)?w.fromJSDate(h):null!=h&&"object"==typeof h&&"toDateTime"in h?h.toDateTime():h;case"expression-list":{const e=[];for(const t of r.value)e.push(this._evaluateNode(t,o,u,l,c));return e}case"unary-expression":return b(this._evaluateNode(r.expr,o,u,l,c));case"binary-expression":switch(r.operator){case"AND":return A(this._evaluateNode(r.left,o,u,l,c),this._evaluateNode(r.right,o,u,l,c));case"OR":return E(this._evaluateNode(r.left,o,u,l,c),this._evaluateNode(r.right,o,u,l,c));case"IS":if("null"!==r.right.type)throw new a(s.UnsupportedIsRhs);return null===this._evaluateNode(r.left,o,u,l,c);case"ISNOT":if("null"!==r.right.type)throw new a(s.UnsupportedIsRhs);return null!==this._evaluateNode(r.left,o,u,l,c);case"IN":{const e=x(this._evaluateNode(r.right,o,u,l,c));return U(this._evaluateNode(r.left,o,u,l,c),e,this.timeZone)}case"NOT IN":{const e=x(this._evaluateNode(r.right,o,u,l,c));return b(U(this._evaluateNode(r.left,o,u,l,c),e,this.timeZone))}case"BETWEEN":{const e=this._evaluateNode(r.left,o,u,l,c),t=this._evaluateNode(r.right,o,u,l,c);return null==e||null==t[0]||null==t[1]?null:n(e,t[0],">=",this.timeZone)&&n(e,t[1],"<=",this.timeZone)}case"NOTBETWEEN":{const e=this._evaluateNode(r.left,o,u,l,c),t=this._evaluateNode(r.right,o,u,l,c);return null==e||null==t[0]||null==t[1]?null:n(e,t[0],"<",this.timeZone)||n(e,t[1],">",this.timeZone)}case"LIKE":return L(this._evaluateNode(r.left,o,u,l,c),this._evaluateNode(r.right,o,u,l,c),r.escape);case"NOT LIKE":return b(L(this._evaluateNode(r.left,o,u,l,c),this._evaluateNode(r.right,o,u,l,c),r.escape));case"<>":case"<":case">":case">=":case"<=":case"=":return n(this._evaluateNode(r.left,o,u,l,c),this._evaluateNode(r.right,o,u,l,c),r.operator,this.timeZone);case"-":case"+":case"*":case"/":case"||":return i(r.operator,this._evaluateNode(r.left,o,u,l,c),this._evaluateNode(r.right,o,u,l,c),this.timeZone)}case"null":case"boolean":case"string":case"number":return r.value;case"date":return r.parsedValue??=d(r.value,"unknown"),r.parsedValue;case"timestamp":return r.parsedValue??=m(r.value,"unknown"),r.parsedValue;case"time":return p(r.value);case"current-time":return"date"===r.mode?F.currentDate(this.timeZone):"time"===r.mode?F.currentTime(this.timeZone):F.currentTimestamp(this.timeZone);case"current-user":return c??null;case"column-reference":return R(o,r.column,this.fieldsIndex,u);case"data-type":return r.value;case"function":{if(this.isAggregate&&e(r.name,r.args.value.length)){const e=[];for(const t of r.args?.value||[]){const r=[];for(const e of l||[])r.push(this._evaluateNode(t,e,u,null,c));e.push(r)}return t(r.name,e)}const a=this._evaluateNode(r.args,o,u,l,c);return g(r.name,a,this.timeZone)}}throw new a(s.UnsupportedSyntax,{node:r.type})}}function Z(e){return!0===e}function x(e){return Array.isArray(e)?e:[e]}function b(e){return null!==e?!0!==e:null}function A(e,t){return null!=e&&null!=t?!0===e&&!0===t:!1!==e&&!1!==t&&null}function E(e,t){return null!=e&&null!=t?!0===e||!0===t:!0===e||!0===t||null}function U(e,t,r){if(null==e)return null;let a=!1;for(const s of t)if(null==s)a=null;else{if(e===s){a=!0;break}if(o(e)&&o(s)&&(a=n(e,s,"="),a))break}return a}const k="-[]/{}()*+?.\\^$|";var V;function q(e,t){const r=t;let a="",s=V.Normal;for(let i=0;i<e.length;i++){const t=e.charAt(i);switch(s){case V.Normal:t===r?s=V.Escaped:k.includes(t)?a+="\\"+t:a+="%"===t?".*":"_"===t?".":t;break;case V.Escaped:k.includes(t)?a+="\\"+t:a+=t,s=V.Normal}}return new RegExp("^"+a+"$","m")}function L(e,t,r){if(null==e)return null;return q(t,r).test(e)}function j(e){return e&&"object"==typeof e.attributes}function R(e,t,a,s){if("getAttributeSQL"in s)return s.getAttributeSQL(e,t);const i=s.getAttribute(e,t),n=a?.get(t);return null==i||"esriFieldTypeDate"!==n?.type&&"date"!==n?.type?null==i||"esriFieldTypeDateOnly"!==n?.type&&"date-only"!==n?.type?null==i||"esriFieldTypeTimeOnly"!==n?.type&&"time-only"!==n?.type?null==i||"esriFieldTypeTimestampOffset"!==n?.type&&"timestamp-offset"!==n?.type?i:new N(i):T.fromReader(i):r.fromReader(i):f(new Date(i),a?.getLuxonTimeZone(n.name)??I.utcInstance)}!function(e){e[e.Normal=0]="Normal",e[e.Escaped=1]="Escaped"}(V||(V={}));const C={getAttribute:(e,t)=>(j(e)?e.attributes:e)[t]};export{D as default};