Example #1
0
        /// <summary>
        /// Create result set grouped by the first column according to <see cref="PDO.FETCH_GROUP"/>.
        /// </summary>
        private protected static PhpArray /*!!*/ GroupResult(PhpArray result, PDO_FETCH style)
        {
            if (result.IsEmpty())
            {
                return(result);
            }

            // hasNumKeys: when FETCH_NUM or FETCH_BOTH
            var fetch      = style & ~PDO_FETCH.Flags;
            var hasNumKeys =
                fetch == PDO_FETCH.FETCH_NUM ||
                fetch == PDO_FETCH.FETCH_BOTH ||
                fetch == PDO_FETCH.Default; // == FETCH_BOTH

            var grouped_result = new PhpArray();
            var resultenum     = result.GetFastEnumerator();

            while (resultenum.MoveNext())
            {
                var row = resultenum.CurrentValue.AsArray();
                if (row == null)
                {
                    throw new InvalidOperationException();              // row is expected to be array, check flags before grouping results
                }
                // We remove the first column and use it to group rows
                var firstCol = row.RemoveFirst();

                // For numeric keys
                // => Always remove the 0 key (FETCH_NUM: does nothing, FETCH_BOTH: remove remaining)
                // => Reindex starting from 0
                if (hasNumKeys && (firstCol.Key == 0 || row.Remove(0)))
                {
                    row.ReindexIntegers(0);
                }

                PhpArray group;
                if (grouped_result.TryGetValue(firstCol.Value, out var existing))
                {
                    group = (PhpArray)existing.Object;
                }
                else
                {
                    grouped_result.Add(firstCol.Value, group = new PhpArray());
                }

                group.Add(row);
            }

            //
            return(grouped_result);
        }
Example #2
0
        internal bool setFetchMode(PDO_FETCH mode, ReadOnlySpan <PhpValue> args)
        {
            switch (mode & ~PDO_FETCH.Flags)
            {
            case PDO_FETCH.Default:
            case PDO_FETCH.FETCH_LAZY:
            case PDO_FETCH.FETCH_ASSOC:
            case PDO_FETCH.FETCH_NUM:
            case PDO_FETCH.FETCH_BOTH:
            case PDO_FETCH.FETCH_OBJ:
            case PDO_FETCH.FETCH_BOUND:
            case PDO_FETCH.FETCH_NAMED:
            case PDO_FETCH.FETCH_KEY_PAIR:
                if (args.Length != 0)
                {
                    HandleError("fetch mode doesn't allow any extra arguments");
                    return(false);
                }

                // ok
                break;

            case PDO_FETCH.FETCH_COLUMN:
                if (args.Length != 1)
                {
                    HandleError("fetch mode requires the colno argument");
                    return(false);
                }
                else if (args[0].IsLong(out var l))
                {
                    _fetch_column = (int)l;
                    break;
                }
                else
                {
                    HandleError("colno must be an integer");
                    return(false);
                }

            case PDO_FETCH.FETCH_CLASS:

                _default_fetch_class_args = default;
                _default_fetch_class      = null;

                if ((mode & PDO_FETCH.FETCH_CLASSTYPE) != 0)
                {
                    // will be getting its class name from 1st column
                    if (args.Length != 0)
                    {
                        HandleError("fetch mode doesn't allow any extra arguments");
                        return(false);
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    if (args.Length == 0)
                    {
                        HandleError("fetch mode requires the classname argument");
                        return(false);
                    }
                    else if (args.Length > 2)
                    {
                        HandleError("too many arguments");
                        return(false);
                    }
                    else if (args[0].IsString(out var name))
                    {
                        _default_fetch_class = Context.GetDeclaredTypeOrThrow(name, autoload: true);
                        if (_default_fetch_class != null)
                        {
                            if (args.Length > 1)
                            {
                                var ctorargs = args[1].AsArray();
                                if (ctorargs == null && !args[1].IsNull)
                                {
                                    HandleError("ctor_args must be either NULL or an array");
                                    return(false);
                                }
                                else if (ctorargs != null && ctorargs.Count != 0)
                                {
                                    _default_fetch_class_args = ctorargs.GetValues();     // TODO: deep copy
                                }
                            }

                            break;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        HandleError("classname must be a string");
                        return(false);
                    }
                }

            //case PDO_FETCH.FETCH_INTO:
            //    if (args.Length != 1)
            //    {
            //        RaiseError("fetch mode requires the object parameter");
            //        return false;
            //    }
            //    else
            //    {
            //        FetchClassInto = args[0].AsObject();
            //        if (FetchClassInto == null)
            //        {
            //            RaiseError("object must be an object");
            //            return false;
            //        }

            //        m_fetchStyle = mode;
            //        return true;
            //    }

            //default:
            //    RaiseError("Invalid fetch mode specified");
            //    return false;

            default:
                throw new NotImplementedException(mode.ToString());
            }

            //
            _default_fetch_type = mode;

            return(true);
        }
Example #3
0
 /// <summary>
 /// Set the default fetch mode for this statement
 ///
 /// </summary>
 /// <param name="mode">The fetch mode.</param>
 /// <param name="args">
 /// args[0] For FETCH_COLUMN : column number. For FETCH_CLASS : the class name. For FETCH_INTO, the object.
 /// args[1] For FETCH_CLASS : the constructor arguments.
 /// </param>
 /// <returns>Returns TRUE on success or FALSE on failure</returns>
 public bool setFetchMode(PDO_FETCH mode, params PhpValue[] args) => setFetchMode(mode, args.AsSpan());
Example #4
0
        public virtual PhpArray fetchAll(PDO_FETCH fetch_style = default, PhpValue fetch_argument = default, PhpArray ctor_args = null)
        {
            var style = fetch_style != PDO_FETCH.Default ? fetch_style : _default_fetch_type;

            var flags = style & PDO_FETCH.Flags;

            if (style == PDO_FETCH.FETCH_COLUMN)
            {
                if (fetch_argument.IsLong(out var l))
                {
                    _fetch_column = (int)l;
                }
                else
                {
                    HandleError("The fetch_argument must be an integer for FETCH_COLUMN.");
                    return(null);
                }
            }

            if ((style & PDO_FETCH.FETCH_CLASS) != 0 && !fetch_argument.IsEmpty)
            {
                if (!setFetchMode(fetch_style, fetch_argument, ctor_args))
                {
                    return(null);
                }
            }

            var result = new PhpArray();

            switch (style)
            {
            case PDO_FETCH.FETCH_KEY_PAIR:

                while (Result.TryReadRow(out var oa, out _))
                {
                    // 1st col => 2nd col
                    result[PhpValue.FromClr(oa[0]).ToIntStringKey()] = PhpValue.FromClr(oa[1]);
                }
                break;

            case PDO_FETCH.FETCH_UNIQUE:

                //Debug.Assert(m_dr.FieldCount >= 1);
                while (Result.TryReadRow(out var oa, out var names))
                {
                    // 1st col => [ 2nd col, 3rd col, ... ]
                    result[PhpValue.FromClr(oa[0]).ToIntStringKey()] = AsAssocArray(oa, names, 1);
                }
                break;

            default:

                for (; ;)
                {
                    var value = fetch(style);
                    if (value.IsFalse)
                    {
                        break;
                    }

                    result.Add(value);
                }

                break;
            }


            // Handle FETCH_GROUP case
            if (flags == PDO_FETCH.FETCH_GROUP)
            {
                result = GroupResult(result, style);
            }

            //
            return(result);
        }
Example #5
0
        /// <inheritDoc />
        public bool setFetchMode(params PhpValue[] args)
        {
            PDO_FETCH fetch = PDO_FETCH.FETCH_USE_DEFAULT;

            if (args.Length > 0)
            {
                PhpValue fetchMode = args[0];

                if (fetchMode.IsInteger())
                {
                    int value = (int)fetchMode.Long;
                    if (Enum.IsDefined(typeof(PDO_FETCH), value))
                    {
                        fetch = (PDO_FETCH)value;

                        this.m_fetchStyle = fetch;
                    }
                    else
                    {
                        m_pdo.HandleError(new PDOException("Given PDO_FETCH constant is not implemented."));
                    }
                }
            }

            if (fetch == PDO_FETCH.FETCH_COLUMN)
            {
                int colNo = -1;
                if (args.Length > 1)
                {
                    if (args[1].IsInteger())
                    {
                        colNo           = (int)args[1].ToLong();
                        this.FetchColNo = colNo;
                    }
                    else
                    {
                        m_pdo.HandleError(new PDOException("General error: colno must be an integer"));
                    }
                }
                else
                {
                    m_pdo.HandleError(new PDOException("General error: fetch mode requires the colno argument"));

                    //TODO what to do if missing parameter ?
                    //fetch = PDO_FETCH.FETCH_USE_DEFAULT;
                }
            }
            string className = null;

            if (fetch == PDO_FETCH.FETCH_CLASS)
            {
                if (args.Length > 1)
                {
                    className           = args[1].ToStringOrNull();
                    this.FetchClassName = className;

                    if (args.Length > 2)
                    {
                        this.FetchClassCtorArgs = args[2].AsArray()?.GetValues();
                    }
                }
                else
                {
                    throw new PDOException("General error: fetch mode requires the classname argument.");
                }
            }

            return(true);
        }
Example #6
0
        public PDOStatement query(string statement, params PhpValue[] args)
        {
            PDOStatement stmt = new PDOStatement(this, statement, null);

            PDO_FETCH fetch = PDO_FETCH.FETCH_USE_DEFAULT;

            if (args.Length > 0)
            {
                PhpValue fetchMode = args[0];
                if (fetchMode.IsInteger())
                {
                    int value = (int)fetchMode.Long;
                    if (Enum.IsDefined(typeof(PDO_FETCH), value))
                    {
                        fetch = (PDO_FETCH)value;
                    }
                }
            }
            int?colNo = null;

            if (fetch == PDO_FETCH.FETCH_COLUMN)
            {
                if (args.Length > 2)
                {
                    colNo = (int)args[1].ToLong();
                }
                else
                {
                    //TODO what to do if missing parameter ?
                    fetch = PDO_FETCH.FETCH_USE_DEFAULT;
                }
            }
            string   className = null;
            PhpArray ctorArgs  = null;

            if (fetch == PDO_FETCH.FETCH_CLASS)
            {
                if (args.Length > 2)
                {
                    className = args[1].ToStringOrNull();
                    if (args.Length > 3)
                    {
                        ctorArgs = args[2].ArrayOrNull();
                    }
                }
                else
                {
                    //TODO what to do if missing parameter ?
                    fetch = PDO_FETCH.FETCH_USE_DEFAULT;
                }
            }
            PhpValue?fetchObject = null;

            if (fetch == PDO_FETCH.FETCH_OBJ)
            {
                if (args.Length > 2)
                {
                    fetchObject = args[1];
                    if (fetchObject.Value.IsNull)
                    {
                        //TODO passed object is null
                    }
                }
                else
                {
                    //TODO what to do if missing parameter ?
                    fetch = PDO_FETCH.FETCH_USE_DEFAULT;
                }
            }

            if (stmt.execute())
            {
                return(stmt);
            }
            else
            {
                return(null);
            }
        }
Example #7
0
        /// <inheritDoc />
        public bool setFetchMode(params PhpValue[] args)
        {
            PDO_FETCH fetch = PDO_FETCH.FETCH_USE_DEFAULT;

            PhpValue fetchMode = args[0];

            if (fetchMode.IsInteger())
            {
                int value = (int)fetchMode.Long;
                if (Enum.IsDefined(typeof(PDO_FETCH), value))
                {
                    fetch = (PDO_FETCH)value;

                    this.m_fetchStyle = fetch;
                }
                else
                {
                    throw new PDOException("Given PDO_FETCH constant is not implemented.");
                }
            }

            if (fetch == PDO_FETCH.FETCH_COLUMN)
            {
                int colNo = -1;
                if (args.Length > 1)
                {
                    if (args[1].IsInteger())
                    {
                        colNo           = (int)args[1].ToLong();
                        this.FetchColNo = colNo;
                    }
                    else
                    {
                        throw new PDOException("General error: colno must be an integer");
                    }
                }
                else
                {
                    throw new PDOException("General error: fetch mode requires the colno argument");

                    //TODO what to do if missing parameter ?
                    //fetch = PDO_FETCH.FETCH_USE_DEFAULT;
                }
            }
            string   className = null;
            PhpArray ctorArgs  = null;

            if (fetch == PDO_FETCH.FETCH_CLASS)
            {
                if (args.Length > 2)
                {
                    className           = args[1].ToStringOrNull();
                    this.FetchClassName = className;

                    if (args.Length > 3)
                    {
                        ctorArgs = args[2].ArrayOrNull();
                    }
                }
                else
                {
                    throw new PDOException("General error: fetch mode requires the classname argument.");

                    //TODO what to do if missing parameter ?
                    //fetch = PDO_FETCH.FETCH_USE_DEFAULT;
                }
            }
            //TODO: FETCH_OBJ does not require additional parameters

            /*PhpValue? fetchObject = null;
             * if (fetch == PDO_FETCH.FETCH_OBJ)
             * {
             *  if (args.Length > 2)
             *  {
             *      fetchObject = args[1];
             *      if (fetchObject.Value.IsNull)
             *      {
             *          //TODO passed object is null
             *      }
             *  }
             *  else
             *  {
             *      //TODO what to do if missing parameter ?
             *      fetch = PDO_FETCH.FETCH_USE_DEFAULT;
             *  }
             * }*/

            return(true);
        }