/// <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); }
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); }
/// <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());
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); }
/// <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); }
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); } }
/// <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); }