예제 #1
0
 public _MemberAccessingFailure(
     Schema.Field field, _MemberAccessor ma,
     string nextMemberName, string cause)
 {
     this.field          = field;
     this.memberAccessor = ma;
     this.nextMemberName = nextMemberName;
     this.cause          = cause;
 }
예제 #2
0
        /// <summary>
        /// Converts a <see cref="Document" /> object to a <see cref="LuceneDocument" /> object.
        /// </summary>
        /// <param name="document">The Document object</param>
        /// <param name="schema">The schema.</param>
        /// <param name="facetBuilder">The Lucene facet builder.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidOperationException">Cannot index a Document that does not have an _id.</exception>
        /// <exception cref="SchemaException">The fieldName '{fieldName}'</exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException">Cannot index a Document that does not have an _id.</exception>
        public static LuceneDocument ToLuceneDocument(this Document document, Schema schema = null, LuceneFacetBuilder facetBuilder = null)
        {
            if (document == null)
                throw new ArgumentNullException(nameof(document));
            if (schema == null)
                schema = Schema.CreateDefault();

            var documentDictionary = document.AsDictionary();
            if (!documentDictionary.ContainsKey(Schema.StandardField.ID))
                throw new InvalidOperationException("Cannot index a Document that does not have an _id.");

            var luceneDocument = new LuceneDocument();

            // Make sure the _id field is the first field added to the Lucene document
            var keys = documentDictionary.Keys.Except(new[] { Schema.StandardField.ID }).ToList();
            keys.Insert(0, Schema.StandardField.ID);

            foreach (var fieldName in keys)
            {
                // Validate fieldName - must not contain space or Lucene QueryParser illegal characters.
                if (_queryParserIllegalCharsRegex.IsMatch(fieldName))
                    throw new SchemaException($"The fieldName '{fieldName}' contains illegal characters.");

                Schema.Field schemaField = null;
                if (!schema.Fields.TryGetValue(fieldName, out schemaField))
                {
                    schemaField = new Schema.Field
                    {
                        Name = fieldName
                    };
                    schema.Fields.TryAdd(fieldName, schemaField);
                }

                var fieldValue = documentDictionary[fieldName];
                var luceneFields = fieldValue.ToLuceneFields(schemaField);
                foreach (var luceneField in luceneFields)
                    luceneDocument.Add(luceneField);
            }

            // The full-text field is always auto-generated and added to the Lucene document.
            var fullText = document.ToLuceneFullTextString();
            luceneDocument.Add(new TextField(Schema.StandardField.FULL_TEXT, fullText, FieldStore.NO));

            // Check if the document has the special _categories field,
            // which means that we need to create facets for it.
            if (document.HasCategories() && facetBuilder != null)
                luceneDocument = facetBuilder.RebuildDocumentWithFacets(luceneDocument, document, schema);

            return luceneDocument;
        }
예제 #3
0
            private void AnnotateIndexes( )
            {
                // if no pkey present, generate a system PKey
                if (!mSchema.Fields.Any(f => f.Attributes.HasAttribute(Attribs.PKey)))
                {
                    // -1 ordinal to signify index is not an actual field (schema member)
                    pkeyOrdinal = pkeyOrdinal.Value(-1);
                    var field = new Schema.Field(DataType.Int);
                    field.Name       = "RowKey";
                    field.Attributes = Attribs.PKey;

                    var indexKey = new Index((int)pkeyOrdinal.Value(), field);
                    indexMap.Add(indexKey.Ordinal, indexKey);
                    nameIdxMap.Add(indexKey.Name, indexKey.Ordinal);
                }

                // iterate fields now to determine what indexes to build
                var idx = 0;

                while (idx < mSchema.Fields.Count)
                {
                    var field = mSchema.Fields[idx];

                    if (field.Is(Attribs.PKey))
                    {
                        if (pkeyOrdinal.Value() == null)
                        {
                            pkeyOrdinal = pkeyOrdinal.Value(idx);

                            var indexKey = new Index((int)pkeyOrdinal.Value(), field);
                            indexMap.Add(indexKey.Ordinal, indexKey);
                            nameIdxMap.Add(indexKey.Name, indexKey.Ordinal);
                        }
                        else
                        {
                            ++idx;
                            continue;
                        }
                    }
                    else if (field.Is(Attribs.Index))
                    {
                        var index = new Index(idx, field);
                        indexMap.Add(idx, index);
                        nameIdxMap.Add(index.Name, index.Ordinal);
                    }

                    ++idx;
                }
            }
예제 #4
0
        private Schema.Field _GetField(int rowOffset, int colOffset)
        {
            if (_fieldMap == null)
            {
                _fieldMap = new FieldMap();
                foreach (var field in _schema)
                {
                    _fieldMap.Add(
                        field.rowOffset + "," + field.colOffset, field
                        );
                }
            }
            var k = rowOffset + "," + colOffset;

            Schema.Field v = null;
            _fieldMap.TryGetValue(k, out v);
            return(v);
        }
예제 #5
0
        public FieldSelection(
            string name,
            string alias,
            IEnumerable <Argument> arguments,
            IEnumerable <Directive> directives,
            IEnumerable <FieldSelection> selectionSet,
            Schema.Field field,
            GraphQLLocation location,
            IValueAccessor valueAccessor)
        {
            Check.IsNotNullOrWhiteSpace(name, nameof(name));
            Check.IsNotNull(field, nameof(field));
            Check.IsNotNull(location, nameof(location));
            Check.IsNotNull(valueAccessor, nameof(valueAccessor));

            Name          = name;
            Alias         = alias;
            Arguments     = arguments;
            Directives    = directives;
            SelectionSet  = selectionSet;
            Field         = field;
            Location      = location;
            ValueAccessor = valueAccessor;
        }
예제 #6
0
        private static List<Field> ToLuceneFields(this IDictionary<string, object> dictionary, Schema.Field parentSchemaField)
        {
            var luceneFields = new List<Field>();

            var childSchema = parentSchemaField.ObjectSchema ?? new Schema { Name = parentSchemaField.Name };

            if (parentSchemaField.DataType == Schema.DataType.Array)
                parentSchemaField.ArrayElementDataType = Schema.DataType.Object;

            parentSchemaField.ObjectSchema = childSchema;

            foreach (var fieldName in dictionary.Keys)
            {
                var childField = dictionary[fieldName];
                var childFieldDataType = GetFieldDataType(childField);

                var childSchemaField = new Schema.Field
                {
                    Name = $"{parentSchemaField.Name}.{fieldName}",
                    DataType = childFieldDataType
                };
                childSchema.Fields.TryAdd(childSchemaField.Name, childSchemaField);

                switch (childFieldDataType)
                {
                    case Schema.DataType.Null:
                    case Schema.DataType.Guid:
                    case Schema.DataType.Text:
                    case Schema.DataType.Number:
                    case Schema.DataType.DateTime:
                    case Schema.DataType.Boolean:
                        luceneFields.AddRange(childField.ToLuceneFields(childSchemaField));
                        break;

                    case Schema.DataType.Array:
                        var array = childField as IList;
                        if (array != null)
                            luceneFields.AddRange(array.ToLuceneFields(childSchemaField));
                        break;

                    case Schema.DataType.Object:
                        var nestedDictionary = childField as IDictionary<string, object>;
                        if (nestedDictionary != null)
                            luceneFields.AddRange(nestedDictionary.ToLuceneFields(childSchemaField));
                        break;
                }
            }

            return luceneFields;
        }
예제 #7
0
        private static List<Field> ToLuceneFields(this IList list, Schema.Field schemaField)
        {
            var luceneFields = new List<Field>();
            if (list.Count > 0)
            {
                Schema.Field arrayElementSchemaField = null;

                foreach (var element in list)
                {
                    if (element == null)
                        continue;

                    if (schemaField.ArrayElementDataType == Schema.DataType.Null)
                        schemaField.ArrayElementDataType = GetFieldDataType(element);
                    else if (schemaField.ArrayElementDataType != GetFieldDataType(element))
                        throw new SchemaException($"All the elements of the '{schemaField.Name}' array must be of type '{schemaField.ArrayElementDataType}'");

                    switch (schemaField.ArrayElementDataType)
                    {
                        case Schema.DataType.Guid:
                        case Schema.DataType.Text:
                        case Schema.DataType.Number:
                        case Schema.DataType.DateTime:
                        case Schema.DataType.Boolean:
                            if (arrayElementSchemaField == null && schemaField.ArrayElementDataType != Schema.DataType.Null)
                            {
                                arrayElementSchemaField = new Schema.Field()
                                {
                                    Name = schemaField.Name,
                                    DataType = schemaField.ArrayElementDataType,
                                    IsArrayElement = true
                                };
                            }
                            luceneFields.AddRange(element.ToLuceneFields(arrayElementSchemaField ?? schemaField));
                            break;

                        case Schema.DataType.Array:
                            throw new SchemaException("JSON with nested arrays are currently not supported.");
                            //break;

                        case Schema.DataType.Object:
                            var dictionary = element as IDictionary<string, object>;
                            if (dictionary != null)
                                luceneFields.AddRange(dictionary.ToLuceneFields(schemaField));
                            break;
                    }
                }
            }

            return luceneFields;
        }
예제 #8
0
        private static bool ValidateArguments(IDictionary <string, InputType> variableTypes, GraphQLObject gqlObject, List <GraphQLError> errors, Schema.Field objectField, IEnumerable <Argument> fieldArguments)
        {
            var valid = true;

            foreach (var arg in fieldArguments)
            {
                var inputType = arg.Value.GetType(variableTypes);

                if (!objectField.Arguments.TryGetValue(arg.Name, out var graphQLType))
                {
                    valid = false;

                    errors.Add(new GraphQLError(
                                   $"Unknown argument '{arg.Name}' on field '{objectField.Name}' of type '{gqlObject.GetTypeName()}'.",
                                   new[] { arg.Location }));
                }
                else if (arg.Value is Variable variable)
                {
                    var inputTypeDescription   = inputType.GetTypeDescription();
                    var graphQLTypeDescription = graphQLType.GetTypeDescription();

                    if (!inputTypeDescription.CanBeDownCastTo(graphQLTypeDescription))
                    {
                        valid = false;

                        errors.Add(new GraphQLError(
                                       $"Variable '${arg.Name}' of type '{inputTypeDescription}' used in position expecting type '{graphQLTypeDescription}'.",
                                       new[] { variable.Location, arg.Location }));
                    }
                }

                // todo: validate non-variable values
            }

            return(valid);
        }
예제 #9
0
        /// <summary>
        /// Populates the Schema object with values from the given dictionary.
        /// </summary>
        /// <param name="schema">The Schema.</param>
        /// <param name="dictionary">The dictionary.</param>
        /// <returns></returns>
        internal static Schema PopulateWith(this Schema schema, IDictionary<string, object> dictionary)
        {
            schema._id = dictionary.ContainsKey(Schema.StandardField.ID) ? (Guid?)dictionary[Schema.StandardField.ID] : null;
            schema.Name = dictionary["Name"] as string;

            var fields = dictionary["Fields"] as IList;
            if (fields != null)
            {
                foreach (var field in fields)
                {
                    var fieldDictionary = field as IDictionary<string, object>;
                    if (fieldDictionary != null)
                    {
                        var schemaField = new Schema.Field().PopulateWith(fieldDictionary);
                        schema.Fields.TryAdd(schemaField.Name, schemaField);
                    }
                }
            }

            schema._createdTimestamp = (DateTime?)dictionary[Schema.StandardField.CREATED_TIMESTAMP];
            schema._modifiedTimestamp = (DateTime?)dictionary[Schema.StandardField.MODIFIED_TIMESTAMP];

            return schema;
        }
예제 #10
0
        public IEnumerable <DataObject> GetUntypedEditableReader(ITransaction transaction, IEnumerable <string> readOnlyFields = null)
        {
            SchemaObject schemaObject = Schema.Schema.GetSchemaObject(DataObjectType);

            HashSet <string> fields = new HashSet <string>();

            foreach (Schema.Field field in schemaObject.GetFields())
            {
                fields.Add(field.FieldName);
            }

            fields.AddRange(readOnlyFields);

            ISelectQuery selectQuery = GetBaseQuery(schemaObject, fields, out Dictionary <string, string> tableAliasesByFieldPath);

            DataTable table           = selectQuery.Execute(transaction);
            FieldInfo isEditableField = DataObjectType.GetField("isEditable", BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (DataRow row in table.Rows)
            {
                DataObject dataObject = (DataObject)Activator.CreateInstance(DataObjectType);
                isEditableField.SetValue(dataObject, true);

                foreach (IGrouping <string, string> fieldByPath in fields.GroupBy(field =>
                {
                    if (field.Contains("."))
                    {
                        return(field.Substring(0, field.LastIndexOf('.')));
                    }

                    return(string.Empty);
                }))
                {
                    DataObject objectToSetValueOn = dataObject;
                    if (fieldByPath.Key.Contains("."))
                    {
                        string[] parts = fieldByPath.Key.Split('.');

                        SchemaObject lastSchemaObject = schemaObject;
                        for (int i = 0; i < parts.Length - 1; i++)
                        {
                            Relationship relationship      = lastSchemaObject.GetRelationship(parts[i]);
                            DataObject   relatedDataObject = relationship.GetValue(objectToSetValueOn);

                            if (relatedDataObject == null)
                            {
                                relatedDataObject = (DataObject)Activator.CreateInstance(relationship.RelatedObjectType);
                                relationship.SetPrivateDataCallback(objectToSetValueOn, relatedDataObject);
                            }

                            objectToSetValueOn = relatedDataObject;
                            lastSchemaObject   = relationship.RelatedSchemaObject;
                        }
                    }

                    string fieldAlias = tableAliasesByFieldPath[fieldByPath.Key];
                    foreach (string field in fieldByPath)
                    {
                        string fieldName = field;
                        if (fieldName.Contains('.'))
                        {
                            fieldName = fieldName.Substring(fieldName.LastIndexOf('.') + 1);
                        }

                        string columnName    = $"{fieldAlias}_{fieldName}";
                        object databaseValue = row[columnName];

                        Schema.Field schemaField = schemaObject.GetField(field);
                        schemaField.SetPrivateDataCallback(objectToSetValueOn, databaseValue);
                    }
                }

                yield return(dataObject);
            }
        }
예제 #11
0
        public override JObject EnrichMetadata(string collection, JObject item, Dictionary <string, object> dataContext)
        {
            JObject result = new JObject();

            Schema.CollectionSchema schema = entityService.GetByName(collection);
            if (schema != null && dataContext.TryGetValue("expando", out object relationsObj) && relationsObj is List <string> relations)
            {
                foreach (string relName in relations)
                {
                    Schema.Field field = schema.FieldSettings.FirstOrDefault(x => x.Type == "relation" && x.Name == relName);
                    if (field != null)
                    {
                        RelationInfo relationInfo = relationInfoService.GetFromOptions(field, item);

                        var hasRefAttached = relationInfo.Values.Count >= 1;

                        if (!hasRefAttached)
                        {
                            result[field.Name] = relationInfo.IsMultiple ? new JArray() : null;
                            continue;
                        }

                        DataQuery dq = new DataQuery()
                        {
                            PageNumber = 1,
                            PageSize   = 999// make it parametric
                        };

                        BsonDocument b = new BsonDocument();

                        if (relationInfo.IsMultiple)
                        {
                            BsonDocument inc = new BsonDocument
                            {
                                ["$in"] = new BsonArray(relationInfo.Values)
                            };
                            b["_id"] = inc;
                        }
                        else
                        {
                            b["_id"] = relationInfo.Values.FirstOrDefault();
                        }

                        dq.RawQuery = b.ToJson();

                        ItemList subitems = crudService.Query(relationInfo.LookupCollection, dq);

                        if (relationInfo.IsMultiple)
                        {
                            result[field.Name] = subitems.Items;
                        }
                        else
                        {
                            result[field.Name] = subitems.Items.FirstOrDefault();
                        }
                    }
                }
            }

            return(result);
        }