/// <summary> /// Calculates the Numeric Value of the Aggregate as evaluated for the given Binding /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public override object NumericValue(SparqlEvaluationContext context, int bindingID) { INode aggValue; if (context.Binder.IsGroup(bindingID)) { BindingGroup group = context.Binder.Group(bindingID); context.Binder.SetGroupContext(true); aggValue = this._aggregate.Apply(context, group.BindingIDs); context.Binder.SetGroupContext(false); } else { aggValue = this._aggregate.Apply(context); } if (aggValue.NodeType == NodeType.Literal) { ILiteralNode lit = (ILiteralNode)aggValue; if (!lit.Language.Equals(String.Empty)) { //If there's a Language Tag implied type is string so no numeric value throw new RdfQueryException("Cannot calculate the Numeric Value of literal with a language specifier"); } else if (lit.DataType == null) { //Try and infer the Data Type if (SparqlSpecsHelper.IsInteger(lit.Value)) { return(Int64.Parse(lit.Value)); } else if (SparqlSpecsHelper.IsDecimal(lit.Value)) { return(Decimal.Parse(lit.Value)); } else if (SparqlSpecsHelper.IsDouble(lit.Value)) { return(Double.Parse(lit.Value)); } else { throw new RdfQueryException("Cannot calculate the Numeric Value of a literal since it does not appear to be a valid Integer/Decimal/Double"); } } else { switch (SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(lit.DataType)) { case SparqlNumericType.Decimal: return(Decimal.Parse(lit.Value)); case SparqlNumericType.Double: return(Double.Parse(lit.Value)); case SparqlNumericType.Float: return(Single.Parse(lit.Value)); case SparqlNumericType.Integer: return(Int64.Parse(lit.Value)); case SparqlNumericType.NaN: default: throw new RdfQueryException("Cannot calculate the Numeric Value of a literal since its Data Type URI does not correspond to a Data Type URI recognised as a Numeric Type in the SPARQL Specification"); } } } else { throw new RdfQueryException("Cannot calculate the Numeric Value of a non-Literal Node"); } }
/// <summary> /// Determines the Effective Boolean Value of the expression for the given Binding in the given Context /// </summary> /// <param name="context">Evaluation Context</param> /// <param name="bindingID">Binding ID</param> /// <returns></returns> public override bool EffectiveBooleanValue(SparqlEvaluationContext context, int bindingID) { try { //While we could use NumericType or NumericValue for Numeric Expressions we can't guarantee that //this would work properly INode temp = this._expr.Value(context, bindingID); if (temp.NodeType == NodeType.Literal) { ILiteralNode lit = (ILiteralNode)temp; //No DatatType means not numeric if (lit.DataType == null) { return(false); } //Get the Numeric Type from the DataType URI SparqlNumericType type = SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(lit.DataType); //Now check the lexical value switch (type) { case SparqlNumericType.Decimal: //Decimal - just regex on lexical form return(SparqlSpecsHelper.IsDecimal(lit.Value)); case SparqlNumericType.Double: case SparqlNumericType.Float: //Double/Float just regex on lexical form return(SparqlSpecsHelper.IsDouble(lit.Value)); case SparqlNumericType.Integer: //Integer Type so could be any of the supported types switch (lit.DataType.ToString()) { case XmlSpecsHelper.XmlSchemaDataTypeByte: //Byte - have to try parsing it SByte sb; return(SByte.TryParse(lit.Value, out sb)); case XmlSpecsHelper.XmlSchemaDataTypeUnsignedByte: //Unsigned Byte - have to try parsing it Byte b; return(Byte.TryParse(lit.Value, out b) && b >= 0); case XmlSpecsHelper.XmlSchemaDataTypeInt: case XmlSpecsHelper.XmlSchemaDataTypeInteger: case XmlSpecsHelper.XmlSchemaDataTypeLong: case XmlSpecsHelper.XmlSchemaDataTypeShort: //Standard Integer - can just regex on its lexical form return(SparqlSpecsHelper.IsInteger(lit.Value)); case XmlSpecsHelper.XmlSchemaDataTypeNegativeInteger: case XmlSpecsHelper.XmlSchemaDataTypeNonPositiveInteger: //Negative Integer - can just regex on its lexical form //plus ensure that the value starts with a - return(lit.Value.StartsWith("-") && SparqlSpecsHelper.IsInteger(lit.Value)); case XmlSpecsHelper.XmlSchemaDataTypeNonNegativeInteger: case XmlSpecsHelper.XmlSchemaDataTypePositiveInteger: case XmlSpecsHelper.XmlSchemaDataTypeUnsignedInt: case XmlSpecsHelper.XmlSchemaDataTypeUnsignedLong: case XmlSpecsHelper.XmlSchemaDataTypeUnsignedShort: //Positive Integer - can just regex on its lexical form //plus ensure that the value doesn't start with a - return(!lit.Value.StartsWith("-") && SparqlSpecsHelper.IsInteger(lit.Value)); default: //Otherwise not numeric return(false); } default: return(false); } } else { return(false); } } catch (RdfQueryException) { return(false); } }
/// <summary> /// Creates a new Full Text Pattern /// </summary> /// <param name="origPatterns">Original Patterns</param> public FullTextPattern(IEnumerable <TriplePattern> origPatterns) { this._origPatterns.AddRange(origPatterns.OrderBy(tp => tp.Predicate.ToString())); PatternItem matchVar = null; PatternItem searchVar = null; Dictionary <String, PatternItem> firsts = new Dictionary <string, PatternItem>(); Dictionary <String, PatternItem> rests = new Dictionary <string, PatternItem>(); foreach (TriplePattern tp in this._origPatterns) { NodeMatchPattern predItem = tp.Predicate as NodeMatchPattern; if (predItem == null) { continue; } IUriNode predUri = predItem.Node as IUriNode; if (predUri == null) { continue; } switch (predUri.Uri.ToString()) { case FullTextHelper.FullTextMatchPredicateUri: //Extract the Search Term if (searchVar != null) { throw new RdfQueryException("More than one pf:textMatch property specified"); } if (tp.Object.VariableName == null) { this._searchTerm = tp.Object; } else { searchVar = tp.Object; } //Extract the Match Variable if (matchVar != null) { throw new RdfQueryException("More than one pf:textMatch property specified"); } if (tp.Subject.VariableName != null && !tp.Subject.VariableName.StartsWith("_:")) { this._matchVar = tp.Subject; if (this._origPatterns.Count > 1 && searchVar == null) { throw new RdfQueryException("Too many patterns provided"); } } else { matchVar = tp.Subject; } break; case RdfSpecsHelper.RdfListFirst: firsts.Add(tp.Subject.VariableName.ToString(), tp.Object); break; case RdfSpecsHelper.RdfListRest: rests.Add(tp.Subject.VariableName.ToString(), tp.Object); break; default: throw new RdfQueryException("Unexpected pattern"); } } //Use the first and rest lists to determine Match and Score Variables if necessary if (this._matchVar == null) { firsts.TryGetValue(matchVar.VariableName, out this._matchVar); String restKey = rests[matchVar.VariableName].VariableName; firsts.TryGetValue(restKey, out this._scoreVar); } //Use the first and rest lists to determine search term, threshold and limit if necessary if (this._searchTerm == null) { firsts.TryGetValue(searchVar.VariableName, out this._searchTerm); String restKey = rests[searchVar.VariableName].VariableName; firsts.TryGetValue(restKey, out this._thresholdTerm); PatternItem last = rests[restKey]; if (!last.ToString().Equals("<" + RdfSpecsHelper.RdfListNil + ">")) { restKey = rests[restKey].VariableName; firsts.TryGetValue(restKey, out this._limitTerm); } else { //If there is only 2 arguments for the search term determine whether it should actually be a //limit rather than a threshold //Essentially if it is an integer assume that it was meant as a limit INode temp = ((NodeMatchPattern)this._thresholdTerm).Node; if (temp is ILiteralNode) { ILiteralNode lit = (ILiteralNode)temp; if (lit.DataType != null) { if (SparqlSpecsHelper.GetNumericTypeFromDataTypeUri(lit.DataType) == VDS.RDF.Query.Expressions.SparqlNumericType.Integer) { //Is actually a limit this._limitTerm = this._thresholdTerm; this._thresholdTerm = null; } } else { if (SparqlSpecsHelper.IsDecimal(lit.Value) || SparqlSpecsHelper.IsDouble(lit.Value)) { //Remains as a Threshold } else if (SparqlSpecsHelper.IsInteger(lit.Value)) { //Is actually a limit this._limitTerm = this._thresholdTerm; this._thresholdTerm = null; } } } } } if (this._matchVar == null) { throw new RdfQueryException("Failed to specify match variable"); } if (this._searchTerm == null) { this._searchTerm = searchVar; } if (this._searchTerm == null) { throw new RdfQueryException("Failed to specify search terms"); } }