/// <summary>
        /// Validate the MJoin fields submitted
        /// </summary>
        /// <param name="response">DataTables response object to record the errors</param>
        /// <param name="editor">Host Editor instance</param>
        /// <param name="data">Data submitted by the client</param>
        internal void Validate(DtResponse response, Editor editor, Dictionary <string, object> data)
        {
            if (!_set || !data.ContainsKey(_name))
            {
                return;
            }

            _Prepare(editor);
            var list = (Dictionary <string, object>)data[_name];

            foreach (var dataSet in list.Select(item => item.Value as Dictionary <string, object>))
            {
                foreach (var field in _fields)
                {
                    var validation = field.Validate(dataSet, editor);

                    if (validation != null)
                    {
                        response.fieldErrors.Add(new DtResponse.FieldError
                        {
                            name   = _name + "[]." + field.Name(),
                            status = validation
                        });
                    }
                }
            }
        }
Exemple #2
0
        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * Public methods
         */

        /// <summary>
        /// Merge a response object into this one to create a single combined
        /// object. Generally parameters that are defined in the object passed
        /// in as a parameter will overwrite the parameters in this object if
        /// the are defined.
        /// </summary>
        /// <param name="b">Response object to merge in</param>
        /// <returns>Self for chaining</returns>
        public DtResponse Merge(DtResponse b)
        {
            if (b.draw != null)
            {
                this.draw = b.draw;
            }

            if (b.data.Count() != 0)
            {
                this.data = b.data;
            }

            if (b.error != null)
            {
                this.error = b.error;
            }

            if (b.fieldErrors != null)
            {
                this.fieldErrors = b.fieldErrors;
            }

            if (b.id != null)
            {
                this.id = b.id;
            }

            if (b.recordsTotal != null)
            {
                this.recordsTotal = b.recordsTotal;
            }

            if (b.recordsFiltered != null)
            {
                this.recordsFiltered = b.recordsFiltered;
            }

            if (b.options.Count() != 0)
            {
                this.options = b.options;
            }

            if (b.searchPanes != null && b.searchPanes.options != null && b.searchPanes.options.Count() != 0)
            {
                this.searchPanes.options = b.searchPanes.options;
            }
            else if (b.searchPanes == null)
            {
                this.searchPanes = null;
            }

            if (b.files.Count() != 0)
            {
                this.files = b.files;
            }

            return(this);
        }
Exemple #3
0
        /// <summary>
        /// Validate the MJoin fields submitted
        /// </summary>
        /// <param name="response">DataTables response object to record the errors</param>
        /// <param name="editor">Host Editor instance</param>
        /// <param name="data">Data submitted by the client</param>
        internal void Validate(DtResponse response, Editor editor, Dictionary <string, object> data, DtRequest.RequestTypes action)
        {
            if (!_set)
            {
                return;
            }

            _Prepare(editor);
            var list = data.ContainsKey(_name) ?
                       (Dictionary <string, object>)data[_name] :
                       new Dictionary <string, object>();

            // Grouped validation
            for (var i = 0; i < _validators.Count(); i++)
            {
                var res = _validators[i](editor, action, list);

                if (res != "" && res != null)
                {
                    response.fieldErrors.Add(new DtResponse.FieldError
                    {
                        name   = _validatorFields[i],
                        status = res
                    });
                }
            }

            // Field validation
            foreach (var dataSet in list.Select(item => item.Value as Dictionary <string, object>))
            {
                foreach (var field in _fields)
                {
                    var validation = field.Validate(dataSet, editor);

                    if (validation != null)
                    {
                        response.fieldErrors.Add(new DtResponse.FieldError
                        {
                            name   = _name + "[]." + field.Name(),
                            status = validation
                        });
                    }
                }
            }
        }
        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * Internal methods
         */

        /// <summary>
        /// Data "get" request - get the joined data
        /// </summary>
        /// <param name="editor">Host Editor instance</param>
        /// <param name="response">DataTables reponse object for where the data
        /// should be written to</param>
        internal void Data(Editor editor, DtResponse response)
        {
            if (!response.data.Any())
            {
                return;
            }

            _Prepare(editor);

            // If the Editor primary key is join key, then it is read automatically
            // and into Editor's primary key store
            var pkeyIsJoin = _hostField == editor.Pkey() ||
                             _hostField == editor.Table()[0];

            // Check that the joining field is available
            var joinFieldName = _hostField.Split('.')[1];

            if (!pkeyIsJoin && !response.data[0].ContainsKey(joinFieldName))
            {
                throw new Exception(
                          "Join was performed on the field '" + _hostField + "' which was not " +
                          "included in the Editor field list. The join field must be " +
                          "included as a regular field in the Editor instance."
                          );
            }

            // Build the basic query
            var query = editor.Db()
                        .Query("select")
                        .Get(_hostField + " as dteditor_pkey")
                        .Table(editor.Table()[0]);

            if (Order() != null)
            {
                query.Order(Order());
            }

            _ApplyWhere(query);

            foreach (var field in _fields.Where(field => field.Apply("get") && field.GetValue() == null))
            {
                if (field.DbField().IndexOf('.') == -1)
                {
                    query.Get(_table + "." + field.DbField() + " as " + field.DbField());
                }
                else
                {
                    query.Get(field.DbField());
                }
            }

            // Create the joins
            if (_linkTable != null)
            {
                query.Join(_linkTable, _hostField + " = " + _linkHostField);
                query.Join(_table, _childField + " = " + _linkChildField);
            }
            else
            {
                query.Join(_table, _childField + " = " + _hostField);
            }

            var result = query.Exec();

            if (result.Count() == 0)
            {
                return;
            }

            // Map the data to the primary key for fast look up
            var join = new Dictionary <string, List <object> >();
            Dictionary <string, object> row;

            while ((row = result.Fetch()) != null)
            {
                var inner = new Dictionary <string, object>();

                foreach (var field in _fields.Where(field => field.Apply("get")))
                {
                    field.Write(inner, row);
                }

                var lookup = row["dteditor_pkey"].ToString();
                if (!join.ContainsKey(lookup))
                {
                    join.Add(lookup, new List <object>());
                }

                join[lookup].Add(inner);
            }

            // Loop over the data and do a join based on the data available
            foreach (var data in response.data)
            {
                var linkField = pkeyIsJoin
                    ? (data["DT_RowId"].ToString()).Replace(editor.IdPrefix(), "")
                    : data[joinFieldName].ToString();

                data.Add(_name, join.ContainsKey(linkField) ?
                         join[linkField] :
                         new List <object>()
                         );
            }

            // Field options
            foreach (var field in _fields)
            {
                var opts = field.OptionsExec(editor.Db());

                if (opts != null)
                {
                    response.options.Add(_name + "[]." + field.Name(), opts);
                }
            }
        }
Exemple #5
0
        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * Internal methods
         */

        /// <summary>
        /// Data "get" request - get the joined data
        /// </summary>
        /// <param name="editor">Host Editor instance</param>
        /// <param name="response">DataTables response object for where the data
        /// should be written to</param>
        internal void Data(Editor editor, DtResponse response)
        {
            _Prepare(editor);

            if (response.data.Count() != 0)
            {
                // This is something that will likely come in a future version, but it
                // is a relatively low use feature. Please get in touch if this is
                // something you require.
                var pkeyA = editor.Pkey();
                if (pkeyA.Length > 1)
                {
                    throw new Exception("MJoin is not currently supported with a compound primary key for the main table.");
                }

                // If the Editor primary key is join key, then it is read automatically
                // and into Editor's primary key store
                var pkeyIsJoin = _hostField == pkeyA[0] ||
                                 _hostField == editor.Table()[0];

                // Build the basic query
                var query = editor.Db()
                            .Query("select")
                            .Distinct(true)
                            .Get(_hostField + " as dteditor_pkey")
                            .Table(editor.Table()[0]);

                if (Order() != null)
                {
                    query.Order(Order());
                }

                _ApplyWhere(query);

                foreach (var field in _fields.Where(field => field.Apply("get") && field.GetValue() == null))
                {
                    if (field.DbField().IndexOf('.') == -1)
                    {
                        query.Get(_table + "." + field.DbField() + " as " + field.DbField());
                    }
                    else
                    {
                        query.Get(field.DbField());
                    }
                }

                // Create the joins
                if (_linkTable != null)
                {
                    query.Join(_linkTable, _hostField + " = " + _linkHostField);
                    query.Join(_table, _childField + " = " + _linkChildField);
                }
                else
                {
                    query.Join(_table, _childField + " = " + _hostField);
                }

                var readField     = "";
                var joinFieldName = _hostField.Split('.')[1];
                if (NestedData.InData(_hostField, response.data[0]))
                {
                    readField = _hostField;
                }
                else if (NestedData.InData(joinFieldName, response.data[0]))
                {
                    readField = joinFieldName;
                }
                else if (!pkeyIsJoin)
                {
                    throw new Exception(
                              "Join was performed on the field '" + _hostField + "' which was not " +
                              "included in the Editor field list. The join field must be " +
                              "included as a regular field in the Editor instance."
                              );
                }

                // There appears to be a bug in the MySQL drivers for .NETCore whereby if there is
                // only one result in the original data set, then it can only read one result into
                // the new data set when using WHERE IN. Any other number of rows is fine. Tried
                // different versions of the server and driver but to no avail, so this is a workaround.
                if (editor.Db().DbType() != "mysql" || response.data.Count != 1)
                {
                    // Get list of pkey values and apply as a WHERE IN condition
                    // This is primarily useful in server-side processing mode and when filtering
                    // the table as it means only a sub-set will be selected
                    // This is only applied for "sensible" data sets. It will just complicate
                    // matters for really large data sets:
                    // https://stackoverflow.com/questions/21178390/in-clause-limitation-in-sql-server
                    if (response.data.Count < 1000)
                    {
                        var whereIn = new List <object>();

                        foreach (var data in response.data)
                        {
                            whereIn.Add(pkeyIsJoin
                                ? (data["DT_RowId"].ToString()).Replace(editor.IdPrefix(), "")
                                : NestedData.ReadProp(readField, data).ToString()
                                        );
                        }

                        query.WhereIn(_hostField, whereIn);
                    }
                }

                var result = query.Exec();

                // Map the data to the primary key for fast look up
                var join = new Dictionary <string, List <Dictionary <string, object> > >();
                Dictionary <string, object> row;

                while ((row = result.Fetch()) != null)
                {
                    var inner = new Dictionary <string, object>();

                    foreach (var field in _fields.Where(field => field.Apply("get")))
                    {
                        field.Write(inner, row);
                    }

                    var lookup = row["dteditor_pkey"].ToString();
                    if (!join.ContainsKey(lookup))
                    {
                        join.Add(lookup, new List <Dictionary <string, object> >());
                    }

                    join[lookup].Add(inner);
                }

                // Loop over the data and do a join based on the data available
                foreach (var data in response.data)
                {
                    var linkField = pkeyIsJoin
                        ? (data["DT_RowId"].ToString()).Replace(editor.IdPrefix(), "")
                        : NestedData.ReadProp(readField, data).ToString();

                    data.Add(_name, join.ContainsKey(linkField)
                        ? join[linkField]
                        : new List <Dictionary <string, object> >()
                             );
                }
            }

            // Field options
            foreach (var field in _fields)
            {
                var opts = field.OptionsExec(editor.Db());

                if (opts != null)
                {
                    response.options.Add(_name + "[]." + field.Name(), opts);
                }
            }
        }
Exemple #6
0
        /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * Internal methods
         */

        /// <summary>
        /// Data "get" request - get the joined data
        /// </summary>
        /// <param name="editor">Host Editor instance</param>
        /// <param name="response">DataTables reponse object for where the data
        /// should be written to</param>
        internal void Data(Editor editor, DtResponse response)
        {
            _Prepare(editor);

            // This is something that will likely come in a future version, but it
            // is a relatively low use feature. Please get in touch if this is
            // something you require.
            var pkeyA = editor.Pkey();

            if (pkeyA.Length > 1)
            {
                throw new Exception("MJoin is not currently supported with a compound primary key for the main table.");
            }

            // If the Editor primary key is join key, then it is read automatically
            // and into Editor's primary key store
            var pkeyIsJoin = _hostField == pkeyA[0] ||
                             _hostField == editor.Table()[0];

            // Build the basic query
            var query = editor.Db()
                        .Query("select")
                        .Distinct(true)
                        .Get(_hostField + " as dteditor_pkey")
                        .Table(editor.Table()[0]);

            if (Order() != null)
            {
                query.Order(Order());
            }

            _ApplyWhere(query);

            foreach (var field in _fields.Where(field => field.Apply("get") && field.GetValue() == null))
            {
                if (field.DbField().IndexOf('.') == -1)
                {
                    query.Get(_table + "." + field.DbField() + " as " + field.DbField());
                }
                else
                {
                    query.Get(field.DbField());
                }
            }

            // Create the joins
            if (_linkTable != null)
            {
                query.Join(_linkTable, _hostField + " = " + _linkHostField);
                query.Join(_table, _childField + " = " + _linkChildField);
            }
            else
            {
                query.Join(_table, _childField + " = " + _hostField);
            }

            var result = query.Exec();

            if (result.Count() != 0)
            {
                var readField     = "";
                var joinFieldName = _hostField.Split('.')[1];

                if (NestedData.InData(_hostField, response.data[0]))
                {
                    readField = _hostField;
                }
                else if (NestedData.InData(joinFieldName, response.data[0]))
                {
                    readField = joinFieldName;
                }
                else if (!pkeyIsJoin)
                {
                    throw new Exception(
                              "Join was performed on the field '" + _hostField + "' which was not " +
                              "included in the Editor field list. The join field must be " +
                              "included as a regular field in the Editor instance."
                              );
                }

                // Map the data to the primary key for fast look up
                var join = new Dictionary <string, List <object> >();
                Dictionary <string, object> row;

                while ((row = result.Fetch()) != null)
                {
                    var inner = new Dictionary <string, object>();

                    foreach (var field in _fields.Where(field => field.Apply("get")))
                    {
                        field.Write(inner, row);
                    }

                    var lookup = row["dteditor_pkey"].ToString();
                    if (!join.ContainsKey(lookup))
                    {
                        join.Add(lookup, new List <object>());
                    }

                    join[lookup].Add(inner);
                }

                // Loop over the data and do a join based on the data available
                foreach (var data in response.data)
                {
                    var linkField = pkeyIsJoin
                        ? (data["DT_RowId"].ToString()).Replace(editor.IdPrefix(), "")
                        : NestedData.ReadProp(readField, data).ToString();

                    data.Add(_name, join.ContainsKey(linkField)
                        ? join[linkField]
                        : new List <object>()
                             );
                }
            }

            // Field options
            foreach (var field in _fields)
            {
                var opts = field.OptionsExec(editor.Db());

                if (opts != null)
                {
                    response.options.Add(_name + "[]." + field.Name(), opts);
                }
            }
        }