/// <inheritdoc />
        public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
        {
            if (_rowColumns[i].GetLength() > _rowColumns[i].BufferLength)//data truncation
            {
                MYSQL_BIND[] newbind = new MYSQL_BIND[1];
                newbind[0] = new MYSQL_BIND();
                var ft = new MYSQL_FIELD();
                ft.Type      = enum_field_types.MYSQL_TYPE_BLOB;
                ft.MaxLength = (uint)length;
                newbind[0].InitForBind(ft, Stmt._nativeConnection);

                sbyte errorCode = Stmt.mysql_stmt_fetch_column(newbind, (uint)i, (uint)fieldOffset);
                if (errorCode != 0)
                {
                    throw new MySqlException(Stmt);
                }

                long result = Math.Min(length, newbind[0].GetLength() - fieldOffset);
                newbind[0].GetBytes(buffer, (uint)result);
                newbind[0].Dispose();
                return(result);
            }
            else
            {
                _rowColumns[i].GetBytes(buffer, (uint)length);
                return(_rowColumns[i].GetLength());
            }
        }
Exemplo n.º 2
0
        // Update by Omar del Valle Rodríguez ([email protected])
        // In order support CommandBehavior.CloseConnection
        internal LiteralQueryStatement(IntPtr resultPtr, MySQLConnection connection, bool closeConnection)
        {
            _nativeResult = new NativeResult(resultPtr);
            // Add by Omar del Valle Rodríguez ([email protected])
            // Save if close connection after close MySQLDataReader
            m_CloseConnection = closeConnection;

            this._connection = connection;
            dt = new DataTable();
            uint  i; ulong j;
            uint  num_fields = _nativeResult.mysql_num_fields();
            ulong num_rows   = _nativeResult.mysql_num_rows();
            List <QueryFieldDescription> fields = new List <QueryFieldDescription>();

            for (i = 0; i < num_fields; i++)
            {
                var field = new MYSQL_FIELD();
                var ptr   = _nativeResult.mysql_fetch_field_direct(i);
                Marshal.PtrToStructure(ptr, field);

                dt.Columns.Add(field.Name);

                //Type ftype = MySqlField.MysqltoNetType(field);
                var mySqlField = new QueryFieldDescription(field.Name, (enum_field_types)field.Type, field.MaxLength, field.Length, field.Flags);
                if (mySqlField.FieldType != null)
                {
                    dt.Columns[field.Name].DataType = mySqlField.FieldType;
                    if (dt.Columns[field.Name].DataType == System.Type.GetType("System.Byte[]"))
                    {
                        dt.Columns[field.Name].ExtendedProperties.Add("max_length", (int)field.MaxLength);
                    }
                }
                fields.Add(mySqlField);
            }

            for (j = 0; j < num_rows; j++)
            {
                IntPtr myrow = _nativeResult.mysql_fetch_row();
                if (myrow == IntPtr.Zero)
                {
                    throw new MySqlException(connection.NativeConnection);
                }
                DataRow dr = dt.NewRow();

                /* for BLOB support
                 * "Christophe Ravier" <*****@*****.**> 2003-11-27*/
                var lengths = _nativeResult.mysql_fetch_lengths((int)num_fields);

                for (i = 0; i < num_fields; i++)
                {
                    QueryFieldDescription queryFieldDescription = fields[(int)i];

                    IntPtr ptr = Marshal.ReadIntPtr(myrow, (int)i * Marshal.SizeOf <IntPtr>());

                    if (ptr == IntPtr.Zero)
                    {
                        dr[(int)i] = Convert.DBNull;
                    }
                    else if (queryFieldDescription.FieldType == typeof(bool))
                    {
                        dr[(int)i] = GetValidString(ptr) != "0";
                    }
                    else if (queryFieldDescription.FieldType == typeof(byte[]))
                    {
                        int length = (int)lengths[i];
                        var val    = new byte[length];
                        Marshal.Copy(ptr, val, 0, length);

                        dr[(int)i] = val;
                    }
                    else if (queryFieldDescription.FieldType == typeof(short))
                    {
                        dr[(int)i] = Convert.ToInt16(GetValidString(ptr));
                    }
                    else if (queryFieldDescription.FieldType == typeof(ushort))
                    {
                        dr[(int)i] = Convert.ToUInt16(GetValidString(ptr));
                    }
                    else if (queryFieldDescription.FieldType == typeof(byte))
                    {
                        dr[(int)i] = Convert.ToByte(GetValidString(ptr));
                    }
                    else if (queryFieldDescription.FieldType == typeof(sbyte))
                    {
                        dr[(int)i] = Convert.ToSByte(GetValidString(ptr));
                    }
                    else if (queryFieldDescription.FieldType == typeof(decimal))
                    {
                        dr[(int)i] = Convert.ToDecimal(GetValidString(ptr), CultureInfo.InvariantCulture.NumberFormat);
                    }
                    else if (queryFieldDescription.FieldType == typeof(double))
                    {
                        dr[(int)i] = Convert.ToDouble(GetValidString(ptr), CultureInfo.InvariantCulture.NumberFormat);
                    }
                    else if (queryFieldDescription.FieldType == typeof(float))
                    {
                        dr[(int)i] = Convert.ToSingle(GetValidString(ptr), CultureInfo.InvariantCulture.NumberFormat);
                    }
                    else if (queryFieldDescription.FieldType == typeof(int))
                    {
                        dr[(int)i] = Convert.ToInt32(GetValidString(ptr));
                    }
                    else if (queryFieldDescription.FieldType == typeof(uint))
                    {
                        dr[(int)i] = Convert.ToUInt32(GetValidString(ptr));
                    }
                    else if (queryFieldDescription.FieldType == typeof(long))
                    {
                        dr[(int)i] = Convert.ToInt64(GetValidString(ptr));
                    }
                    else if (queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_GEOMETRY)
                    {
                        // TODO: returns empty string
                        string val = GetValidString(ptr);
                        dr[(int)i] = val;
                    }
                    else if (queryFieldDescription.FieldType == typeof(ulong))
                    {
                        if (queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_BIT)
                        {
                            {
                                int byteCount;
                                if (queryFieldDescription.Length <= 8)
                                {
                                    byteCount = 1;
                                }
                                else if (queryFieldDescription.Length <= 16)
                                {
                                    byteCount = 2;
                                }
                                else if (queryFieldDescription.Length <= 24)
                                {
                                    byteCount = 3;
                                }
                                else if (queryFieldDescription.Length <= 32)
                                {
                                    byteCount = 4;
                                }
                                else if (queryFieldDescription.Length <= 32 + 8)
                                {
                                    byteCount = 5;
                                }
                                else if (queryFieldDescription.Length <= 32 + 16)
                                {
                                    byteCount = 6;
                                }
                                else if (queryFieldDescription.Length <= 32 + 24)
                                {
                                    byteCount = 7;
                                }
                                else
                                {
                                    byteCount = 8;
                                }
                                var buffer = new byte[sizeof(long)];
                                for (int l = 0; l < byteCount; l++)
                                {
                                    buffer[l] = Marshal.ReadByte(ptr, l);
                                }

                                dr[(int)i] = BitConverter.ToInt64(buffer, 0);
                            }
                        }
                        else
                        {
                            string val = GetValidString(ptr);
                            if (val == null)
                            {
                                dr[(int)i] = Convert.DBNull;
                            }
                            else
                            {
                                dr[(int)i] = Convert.ToUInt64(val);
                            }
                        }
                    }
                    else if (queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_DATE || queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_DATE)
                    {
                        string val = GetValidString(ptr);
                        dr[(int)i] = DateTime.ParseExact(val, "yyyy-MM-dd", CultureInfo.InvariantCulture.DateTimeFormat);
                    }
                    else if (queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_DATETIME || queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_DATETIME2 ||
                             queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_TIMESTAMP ||
                             queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_TIMESTAMP2)
                    {
                        string val = GetValidString(ptr);
                        dr[(int)i] = DateTime.ParseExact(val, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture.DateTimeFormat);
                    }
                    else if (queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_TIME || queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_TIME2)
                    {
                        string val = GetValidString(ptr);
                        dr[(int)i] = DateTime.ParseExact("0001-01-01 " + val, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture.DateTimeFormat);
                    }
                    else if (queryFieldDescription.Type == enum_field_types.MYSQL_TYPE_YEAR)
                    {
                        string val = GetValidString(ptr);
                        dr[(int)i] = DateTime.ParseExact(val, "yyyy", CultureInfo.InvariantCulture.DateTimeFormat);
                    }
                    else if (queryFieldDescription.FieldType == typeof(DateTime))
                    {
                        string val = GetValidString(ptr);
                        if (val == null)
                        {
                            dr[(int)i] = Convert.DBNull;
                        }
                        else
                        {
                            DateTimeFormatInfo format = new DateTimeFormatInfo();
                            if (val.Length > 20)
                            {
                                dr[(int)i] = DateTime.ParseExact(val, "yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture.DateTimeFormat);
                            }
                            else
                            {
                                if (val.Length > 10)
                                {
                                    dr[(int)i] = DateTime.ParseExact(val, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture.DateTimeFormat);
                                }
                                else
                                {
                                    dr[(int)i] = DateTime.ParseExact(val, "yyyy-MM-dd", CultureInfo.InvariantCulture.DateTimeFormat);
                                }
                            }
                        }
                    }
                    else if (queryFieldDescription.FieldType == typeof(string))
                    {
                        string val = GetValidString(ptr);
                        if (val == null)
                        {
                            dr[(int)i] = Convert.DBNull;
                        }
                        else
                        {
                            dr[(int)i] = val;
                        }
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
                dt.Rows.Add(dr);
            }
        }