An alternative to UBB.threads
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

898 lines
32 KiB

// Copyright (c) 2004-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as published by
// the Free Software Foundation
//
// There are special exceptions to the terms and conditions of the GPL
// as it is applied to this software. View the full text of the
// exception in file EXCEPTIONS in the directory of this software
// distribution.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Data;
using System.IO;
using NUnit.Framework;
namespace MySql.Data.MySqlClient.Tests
{
[TestFixture]
public class PreparedStatements : BaseTest
{
public PreparedStatements()
{
csAdditions += ";ignore prepare=false;";
}
[Test]
public void Simple()
{
execSQL("CREATE TABLE Test (id INT, dec1 DECIMAL(5,2), name VARCHAR(100))");
execSQL("INSERT INTO Test VALUES (1, 345.12, 'abcd')");
MySqlCommand cmd = new MySqlCommand("INSERT INTO Test VALUES(1,345.12,'abcd')", conn);
cmd.Prepare();
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT * FROM Test";
cmd.Prepare();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
Assert.IsTrue(reader.Read());
Assert.AreEqual(1, reader.GetInt32(0));
Assert.AreEqual(345.12, reader.GetDecimal(1));
Assert.AreEqual("abcd", reader.GetString(2));
}
}
[Test]
public void SimplePrepareBeforeParms()
{
execSQL("CREATE TABLE Test (one INTEGER, two INTEGER)");
execSQL("INSERT INTO Test VALUES (1, 2)");
// create the command and prepare the statement
IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM Test WHERE one = ?p1";
// create the parameter
IDbDataParameter p1 = cmd.CreateParameter();
p1.ParameterName = "?p1";
p1.DbType = DbType.Int32;
p1.Precision = (byte)10;
p1.Scale = (byte)0;
p1.Size = 4;
cmd.Parameters.Add(p1);
p1.Value = 1;
cmd.Prepare();
// Execute the reader
using (IDataReader reader = cmd.ExecuteReader())
{
// Fetch the first record
reader.Read();
Assert.AreEqual(1, reader.GetInt32(0));
Assert.AreEqual(2, reader.GetInt32(1));
}
}
[Test]
public void DateAndTimes()
{
execSQL("CREATE TABLE Test (id INT NOT NULL, d DATE, dt DATETIME, tm TIME, ts TIMESTAMP, PRIMARY KEY(id))");
string sql = "INSERT INTO Test VALUES(?id, ?d, ?dt, ?tm, NULL)";
MySqlCommand cmd = new MySqlCommand(sql, conn);
DateTime dt = DateTime.Now;
dt = dt.AddMilliseconds( dt.Millisecond * -1 );
TimeSpan ts = new TimeSpan( 8, 11, 44, 56, 501 );
cmd.Parameters.AddWithValue("?id", 1);
cmd.Parameters.AddWithValue("?d", dt);
cmd.Parameters.AddWithValue("?dt", dt);
cmd.Parameters.AddWithValue("?tm", ts);
cmd.Prepare();
int count = cmd.ExecuteNonQuery();
Assert.AreEqual(1, count, "Records affected by insert");
cmd.CommandText = "SELECT * FROM Test";
cmd.Prepare();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
Assert.AreEqual(1, reader.GetInt32(0), "Id column");
Assert.AreEqual(dt.Date, reader.GetDateTime(1).Date, "Date column");
DateTime dt2 = reader.GetDateTime(2);
Assert.AreEqual(dt.Date, dt2.Date);
Assert.AreEqual(dt.Hour, dt2.Hour);
Assert.AreEqual(dt.Minute, dt2.Minute);
Assert.AreEqual(dt.Second, dt2.Second);
TimeSpan ts2 = reader.GetTimeSpan(3);
Assert.AreEqual(ts.Days, ts2.Days);
Assert.AreEqual(ts.Hours, ts2.Hours);
Assert.AreEqual(ts.Minutes, ts2.Minutes);
Assert.AreEqual(ts.Seconds, ts2.Seconds);
Assert.AreEqual(dt.Date, reader.GetDateTime(4).Date, "Timestamp column");
}
}
[Test]
public void ResetCommandText()
{
execSQL("CREATE TABLE Test (id int, name varchar(100))");
execSQL("INSERT INTO Test VALUES (1, 'Test')");
MySqlCommand cmd = new MySqlCommand("SELECT id FROM Test", conn);
cmd.Prepare();
object o = cmd.ExecuteScalar();
Assert.AreEqual( 1, o );
cmd.CommandText = "SELECT name FROM Test";
cmd.Prepare();
o = cmd.ExecuteScalar();
Assert.AreEqual( "Test", o );
}
[Test]
public void DifferentParameterOrder()
{
execSQL("CREATE TABLE Test (id int NOT NULL AUTO_INCREMENT, " +
"id2 int NOT NULL, name varchar(50) DEFAULT NULL, " +
"id3 int DEFAULT NULL, PRIMARY KEY (id))");
MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, id2, name, id3) " +
"VALUES(?id, ?id2, ?name,?id3)", conn);
MySqlParameter id = new MySqlParameter();
id.ParameterName = "?id";
id.DbType = DbType.Int32;
id.Value = DBNull.Value;
MySqlParameter id2 = new MySqlParameter();
id2.ParameterName = "?id2";
id2.DbType = DbType.Int32;
id2.Value = 2;
MySqlParameter name = new MySqlParameter();
name.ParameterName = "?name";
name.DbType = DbType.String;
name.Value = "Test";
MySqlParameter id3 = new MySqlParameter();
id3.ParameterName = "?id3";
id3.DbType = DbType.Int32;
id3.Value = 3;
cmd.Parameters.Add(id);
cmd.Parameters.Add(id2);
cmd.Parameters.Add(name);
cmd.Parameters.Add(id3);
cmd.Prepare();
Assert.AreEqual(1, cmd.ExecuteNonQuery());
cmd.Parameters.Clear();
id3.Value = DBNull.Value;
name.Value = DBNull.Value;
cmd.Parameters.Add(id);
cmd.Parameters.Add(id2);
cmd.Parameters.Add(id3);
cmd.Parameters.Add(name);
cmd.Prepare();
Assert.AreEqual(1, cmd.ExecuteNonQuery());
cmd.CommandText = "SELECT id3 FROM Test WHERE id=1";
Assert.AreEqual(3, cmd.ExecuteScalar());
cmd.CommandText = "SELECT name FROM Test WHERE id=2";
Assert.AreEqual(DBNull.Value, cmd.ExecuteScalar());
}
[Test]
public void Blobs()
{
execSQL("CREATE TABLE Test (id INT, blob1 LONGBLOB, text1 LONGTEXT)");
MySqlCommand cmd = new MySqlCommand("INSERT INTO Test VALUES (?id, ?blob1, ?text1)", conn);
byte[] bytes = Utils.CreateBlob( 400000 );
string inStr = "This is my text";
cmd.Parameters.AddWithValue("?id", 1);
cmd.Parameters.AddWithValue("?blob1", bytes);
cmd.Parameters.AddWithValue("?text1", inStr);
cmd.Prepare();
int count = cmd.ExecuteNonQuery();
Assert.AreEqual( 1, count );
cmd.CommandText = "SELECT * FROM Test";
cmd.Prepare();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
Assert.IsTrue( reader.Read() );
Assert.AreEqual( 1, reader.GetInt32(0) );
Assert.AreEqual( bytes.Length, reader.GetBytes( 1, 0, null, 0, 0 ));
byte[] outBytes = new byte[ bytes.Length ];
reader.GetBytes( 1, 0, outBytes, 0, bytes.Length );
for (int x=0; x < bytes.Length; x++)
Assert.AreEqual( bytes[x], outBytes[x] );
Assert.AreEqual( inStr, reader.GetString( 2 ) );
}
}
[Test]
public void SimpleTest2()
{
execSQL("CREATE TABLE Test (one integer, two integer, three integer, four integer, five integer, six integer, seven integer)");
execSQL("INSERT INTO Test VALUES (1, 2, 3, 4, 5, 6, 7)");
// create the command and prepare the statement
IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT one, two, three, four, five, six, seven FROM Test";
cmd.Prepare();
// Execute the reader
using (IDataReader reader = cmd.ExecuteReader())
{
// Fetch the first record
reader.Read();
Assert.AreEqual( 1, reader.GetInt32(0) );
Assert.AreEqual( 2, reader.GetInt32(1) );
Assert.AreEqual( 3, reader.GetInt32(2) );
Assert.AreEqual( 4, reader.GetInt32(3) );
Assert.AreEqual( 5, reader.GetInt32(4) );
Assert.AreEqual( 6, reader.GetInt32(5) );
Assert.AreEqual( 7, reader.GetInt32(6) );
}
}
[Test]
public void Bug6271()
{
if (Version < new Version(4, 1)) return;
// Create the table again
execSQL("CREATE TABLE `Test2` (id INT unsigned NOT NULL auto_increment, " +
"`xpDOSG_Name` text,`xpDOSG_Desc` text, `Avatar` MEDIUMBLOB, `dtAdded` DATETIME, `dtTime` TIMESTAMP, " +
"PRIMARY KEY(id)) ENGINE=InnoDB DEFAULT CHARSET=latin1" );
string sql = "INSERT INTO `Test2` (`xpDOSG_Name`,`dtAdded`, `xpDOSG_Desc`,`Avatar`, `dtTime`) " +
"VALUES(?name, ?dt, ?desc, ?Avatar, NULL)";
MySqlCommand cmd = new MySqlCommand(sql, conn);
DateTime dt = DateTime.Now;
dt = dt.AddMilliseconds(dt.Millisecond * -1);
byte[] xpDOSG_Avatar = Utils.CreateBlob(13000);
cmd.Parameters.AddWithValue("?name", "Ceci est un nom");
cmd.Parameters.AddWithValue("?desc", "Ceci est une description facile <EFBFBD> plantouiller");
cmd.Parameters.AddWithValue("?avatar",xpDOSG_Avatar);
cmd.Parameters.AddWithValue("?dt", dt);
cmd.Prepare();
int count = cmd.ExecuteNonQuery();
Assert.AreEqual(1, count);
cmd.CommandText = "SELECT * FROM Test2";
using (MySqlDataReader reader = cmd.ExecuteReader())
{
Assert.IsTrue(reader.Read());
Assert.AreEqual("Ceci est un nom", reader.GetString(1));
Assert.AreEqual(dt.ToString("G"), reader.GetDateTime(4).ToString("G"));
Assert.AreEqual("Ceci est une description facile <EFBFBD> plantouiller", reader.GetString(2));
long len = reader.GetBytes(3, 0, null, 0, 0);
Assert.AreEqual(xpDOSG_Avatar.Length, len);
byte[] outBytes = new byte[len];
reader.GetBytes(3, 0, outBytes, 0, (int)len);
for (int x=0; x < xpDOSG_Avatar.Length; x++)
Assert.AreEqual(xpDOSG_Avatar[x], outBytes[x]);
}
}
[Test]
public void SimpleTest()
{
execSQL("CREATE TABLE Test (one integer, two integer )");
execSQL("INSERT INTO Test VALUES( 1, 2)");
// create the command and prepare the statement
IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM Test where one = ?p1";
// create the parameter
IDbDataParameter p1 = cmd.CreateParameter();
p1.ParameterName = "?p1";
p1.DbType = DbType.Int32;
p1.Precision = (byte)10;
p1.Scale = (byte)0;
p1.Size = 4;
cmd.Parameters.Add(p1);
// prepare the command
cmd.Prepare();
// set the parameter value
p1.Value = 1;
// Execute the reader
IDataReader reader = null;
try
{
reader = cmd.ExecuteReader();
// Fetch the first record
reader.Read();
}
catch (Exception ex)
{
Assert.Fail( ex.Message );
}
finally
{
if (reader != null) reader.Close();
}
}
/// <summary>
/// Bug #13662 Prepare() truncates accented character input
/// </summary>
[Test]
public void InsertAccentedCharacters()
{
if (Version < new Version(4, 1)) return;
execSQL("CREATE TABLE Test (id INT UNSIGNED NOT NULL PRIMARY KEY " +
"AUTO_INCREMENT, input TEXT NOT NULL) CHARACTER SET UTF8");
// COLLATE " +
//"utf8_bin");
using (MySqlConnection conn2 = new MySqlConnection(GetConnectionString(true) +
";charset=utf8"))
{
conn2.Open();
MySqlCommand cmd = new MySqlCommand("INSERT INTO Test(input) " +
"VALUES (?input) ON DUPLICATE KEY UPDATE " +
"id=LAST_INSERT_ID(id)", conn2);
cmd.Parameters.Add(new MySqlParameter("?input", ""));
cmd.Prepare();
cmd.Parameters[0].Value = "irache mart<EFBFBD>nez@yahoo.es aol.com";
cmd.ExecuteNonQuery();
MySqlCommand cmd2 = new MySqlCommand("SELECT input FROM Test", conn2);
Assert.AreEqual("irache mart<EFBFBD>nez@yahoo.es aol.com",
cmd2.ExecuteScalar());
}
}
/// <summary>
/// Bug #13541 Prepare breaks if a parameter is used more than once
/// </summary>
[Test]
public void UsingParametersTwice()
{
if (Version < new Version(4, 1)) return;
execSQL(@"CREATE TABLE IF NOT EXISTS Test (input TEXT NOT NULL,
UNIQUE (input(100)), state INT NOT NULL, score INT NOT NULL)");
MySqlCommand cmd = new MySqlCommand(@"Insert into Test (input,
state, score) VALUES (?input, ?st, ?sc) ON DUPLICATE KEY
UPDATE state=state|?st;", conn);
cmd.Parameters.Add (new MySqlParameter("?input", ""));
cmd.Parameters.Add (new MySqlParameter("?st", Convert.ToInt32(0)));
cmd.Parameters.Add (new MySqlParameter("?sc", Convert.ToInt32(0)));
cmd.Prepare();
cmd.Parameters["?input"].Value = "test";
cmd.Parameters["?st"].Value = 1;
cmd.Parameters["?sc"].Value = 42;
int result = cmd.ExecuteNonQuery();
Assert.AreEqual(1, result);
MySqlDataAdapter da = new MySqlDataAdapter("SELECT * FROM Test", conn);
DataTable dt = new DataTable();
da.Fill(dt);
Assert.AreEqual(1, dt.Rows.Count);
Assert.AreEqual("test", dt.Rows[0]["input"]);
Assert.AreEqual(1, dt.Rows[0]["state"]);
Assert.AreEqual(42, dt.Rows[0]["score"]);
}
/// <summary>
/// Bug #19261 Supplying Input Parameters
/// </summary>
[Test]
public void MoreParametersOutOfOrder()
{
if (Version < new Version(4, 1)) return;
execSQL("CREATE TABLE `Test` (`BlackListID` int(11) NOT NULL auto_increment, " +
"`SubscriberID` int(11) NOT NULL, `Phone` varchar(50) default NULL, " +
"`ContactID` int(11) default NULL, " +
"`AdminJunk` tinyint(1) NOT NULL default '0', " +
"PRIMARY KEY (`BlackListID`), KEY `SubscriberID` (`SubscriberID`))");
IDbCommand cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO `Test`(`SubscriberID`,`Phone`,`ContactID`, " +
"`AdminJunk`) VALUES (?SubscriberID,?Phone,?ContactID, ?AdminJunk);";
MySqlParameter oParameterSubscriberID = new MySqlParameter();
oParameterSubscriberID.ParameterName = "?SubscriberID";
oParameterSubscriberID.DbType = DbType.Int32;
oParameterSubscriberID.Value = 1;
MySqlParameter oParameterPhone = new MySqlParameter();
oParameterPhone.ParameterName = "?Phone";
oParameterPhone.DbType = DbType.String;
oParameterPhone.Value = DBNull.Value;
MySqlParameter oParameterContactID = new MySqlParameter();
oParameterContactID.ParameterName = "?ContactID";
oParameterContactID.DbType = DbType.Int32;
oParameterContactID.Value = DBNull.Value;
MySqlParameter oParameterAdminJunk = new MySqlParameter();
oParameterAdminJunk.ParameterName = "?AdminJunk";
oParameterAdminJunk.DbType = DbType.Boolean;
oParameterAdminJunk.Value = true;
cmd.Parameters.Add(oParameterSubscriberID);
cmd.Parameters.Add(oParameterPhone);
cmd.Parameters.Add(oParameterAdminJunk);
cmd.Parameters.Add(oParameterContactID);
cmd.Prepare();
int cnt = cmd.ExecuteNonQuery();
Assert.AreEqual(1, cnt);
}
/// <summary>
/// Bug #16627 Index and length must refer to a location within the string." when executing c
/// </summary>
[Test]
public void ParameterLengths()
{
if (Version < new Version(4, 1)) return;
execSQL("CREATE TABLE Test (id int, name VARCHAR(255))");
MySqlCommand cmd = new MySqlCommand("INSERT INTO Test VALUES (?id, ?name)", conn);
cmd.Parameters.Add("?id", MySqlDbType.Int32);
cmd.Parameters.Add("?name", MySqlDbType.VarChar);
cmd.Parameters[1].Size = 255;
cmd.Prepare();
cmd.Parameters[0].Value = 1;
cmd.Parameters[1].Value = "short string";
cmd.ExecuteNonQuery();
MySqlDataAdapter da = new MySqlDataAdapter("SELECT * FROM Test", conn);
DataTable dt = new DataTable();
da.Fill(dt);
Assert.AreEqual(1, dt.Rows.Count);
Assert.AreEqual(1, dt.Rows[0]["id"]);
Assert.AreEqual("short string", dt.Rows[0]["name"]);
}
/// <summary>
/// Bug #18570 Unsigned tinyint (NET byte) incorrectly determined param type from param val
/// </summary>
[Test]
public void UnsignedTinyInt()
{
if (Version < new Version(4, 1)) return;
execSQL("CREATE TABLE Test(ID TINYINT UNSIGNED NOT NULL, " +
"Name VARCHAR(50) NOT NULL, PRIMARY KEY (ID), UNIQUE (ID), " +
"UNIQUE (Name))");
execSQL("INSERT INTO Test VALUES ('127', 'name1')");
execSQL("INSERT INTO Test VALUES ('128', 'name2')");
execSQL("INSERT INTO Test VALUES ('255', 'name3')");
string sql = " SELECT count(*) FROM Test WHERE ID = ?id";
MySqlCommand command = new MySqlCommand();
command.CommandText = sql;
command.CommandType = CommandType.Text;
command.Connection = (MySqlConnection)conn;
command.Parameters.AddWithValue("?id", (byte)127);
command.Prepare();
object count = command.ExecuteScalar();
Assert.AreEqual(1, count);
command.Parameters.Clear();
command.Parameters.AddWithValue("?id", (byte)128);
count = command.ExecuteScalar();
Assert.AreEqual(1, count);
command.Parameters.Clear();
command.Parameters.AddWithValue("?id", (byte)255);
count = command.ExecuteScalar();
Assert.AreEqual(1, count);
command.Parameters.Clear();
command.Parameters.AddWithValue("?id", "255");
count = command.ExecuteScalar();
Assert.AreEqual(1, count);
}
/// <summary>
/// Bug #16934 Unsigned values > 2^63 (UInt64) cannot be used in prepared statements
/// </summary>
[Test]
public void UnsignedValues()
{
if (Version < new Version(4, 1)) return;
execSQL("CREATE TABLE Test (ulVal BIGINT UNSIGNED, lVal INT UNSIGNED, " +
"mVal MEDIUMINT UNSIGNED, sVal SMALLINT UNSIGNED)");
MySqlCommand cmd = new MySqlCommand("INSERT INTO Test VALUES (?ulVal, " +
"?lVal, ?mVal, ?sVal)", conn);
cmd.Parameters.Add("?ulVal", MySqlDbType.UInt64);
cmd.Parameters.Add("?lVal", MySqlDbType.UInt32);
cmd.Parameters.Add("?mVal", MySqlDbType.UInt24);
cmd.Parameters.Add("?sVal", MySqlDbType.UInt16);
cmd.Prepare();
cmd.Parameters[0].Value = UInt64.MaxValue;
cmd.Parameters[1].Value = UInt32.MaxValue;
cmd.Parameters[2].Value = 16777215;
cmd.Parameters[3].Value = UInt16.MaxValue;
Assert.AreEqual(1, cmd.ExecuteNonQuery());
cmd.CommandText = "SELECT * FROM Test";
cmd.CommandType = CommandType.Text;
using (MySqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
Assert.AreEqual(UInt64.MaxValue, reader.GetUInt64(0));
Assert.AreEqual(UInt32.MaxValue, reader.GetUInt32(1));
Assert.AreEqual(16777215, reader.GetUInt32(2));
Assert.AreEqual(UInt16.MaxValue, reader.GetUInt16(3));
}
}
/// <summary>
/// Bug #18391 Better error handling for the .NET class "MySqlCommand" needed.
/// </summary>
[Test]
public void PrepareEmptyString()
{
try
{
MySqlCommand cmd = new MySqlCommand("", conn);
cmd.Prepare();
cmd.ExecuteNonQuery();
Assert.Fail("Should not get here");
}
catch (InvalidOperationException)
{
}
}
/// <summary>
/// Bug #14115 Prepare() with compound statements breaks
/// </summary>
[Test]
public void CompoundStatements()
{
execSQL("CREATE TABLE IF NOT EXISTS Test ("+
"id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT," +
"test1 INT UNSIGNED, test2 INT UNSIGNED)");
try
{
MySqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO Test VALUES (NULL, ?t1, ?t2);" +
"SELECT last_insert_id()";
cmd.Parameters.Add("?t1", MySqlDbType.Int32);
cmd.Parameters.Add("?t2", MySqlDbType.Int32);
cmd.Prepare();
Assert.Fail("Should not reach here");
}
catch (Exception)
{
}
}
[Test]
public void SchemaOnly()
{
execSQL("CREATE TABLE Test (id INT, name VARCHAR(50))");
MySqlCommand cmd = new MySqlCommand("SELECT * FROM Test", conn);
cmd.Prepare();
using (MySqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SchemaOnly))
{
reader.Read();
}
}
private int GetPreparedStatementCount()
{
MySqlCommand cmd = new MySqlCommand("SHOW GLOBAL STATUS LIKE 'Prepared%'", conn);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
string s = reader.GetString(1);
return Int32.Parse(s);
}
}
[Test]
public void ClosingCommandsProperly()
{
if (Version < new Version(5, 0)) return;
execSQL("CREATE TABLE Test (id INT, name VARCHAR(50))");
string connStr = GetConnectionString(true) +
";ignore prepare=false";
using (MySqlConnection c = new MySqlConnection(connStr))
{
c.Open();
int initialCount = GetPreparedStatementCount();
for (int i = 0; i < 10; i++)
{
using (MySqlCommand cmd =
new MySqlCommand("INSERT INTO Test VALUES (?id, ?name)", c))
{
cmd.Parameters.Add("?id", MySqlDbType.Int32);
cmd.Parameters.Add("?name", MySqlDbType.VarChar);
cmd.Prepare();
cmd.Parameters[0].Value = i;
cmd.Parameters[1].Value = "foobar";
cmd.ExecuteNonQuery();
}
}
c.Ping();
Assert.AreEqual(initialCount, GetPreparedStatementCount());
}
}
/// <summary>
/// Bug #37968 Prepared statements byte/tinyint causes data corruption.
/// </summary>
[Test]
public void InsertingUnsignedTinyInt()
{
execSQL("DROP TABLE IF EXISTS Test");
execSQL(@"CREATE TABLE Test(id TINYINT UNSIGNED NOT NULL,
id2 INT UNSIGNED, id3 TINYINT UNSIGNED, id4 INT UNSIGNED NOT NULL)");
MySqlCommand cmd = new MySqlCommand("INSERT INTO Test VALUES (?id, ?id2, ?id3, ?id4)", conn);
cmd.Parameters.Add("?id", MySqlDbType.UByte);
cmd.Parameters.Add("?id2", MySqlDbType.UByte);
cmd.Parameters.Add("?id3", MySqlDbType.UByte);
cmd.Parameters.Add("?id4", MySqlDbType.UByte);
cmd.Prepare();
cmd.Parameters[0].Value = 127;
cmd.Parameters[1].Value = 1;
cmd.Parameters[2].Value = 2;
cmd.Parameters[3].Value = 3;
cmd.ExecuteNonQuery();
MySqlDataAdapter da = new MySqlDataAdapter("SELECT * FROM Test", conn);
DataTable dt = new DataTable();
da.Fill(dt);
Assert.AreEqual(1, dt.Rows.Count);
Assert.AreEqual(127, dt.Rows[0][0]);
Assert.AreEqual(1, dt.Rows[0][1]);
Assert.AreEqual(2, dt.Rows[0][2]);
Assert.AreEqual(3, dt.Rows[0][3]);
}
/// <summary>
/// Bug #39275 Inserting negative time value through the use of MySqlParameter throws exception
/// Bug #39294 Reading negative time value greater than -01:00:00 return positive value
/// </summary>
[Test]
public void NegativeTimePrepared()
{
NegativeTime(true);
ReadNegativeTime(true);
}
/// <summary>
/// Bug #39275 Inserting negative time value through the use of MySqlParameter throws exception
/// Bug #39294 Reading negative time value greater than -01:00:00 return positive value
/// </summary>
[Test]
public void NegativeTimeNonPrepared()
{
NegativeTime(false);
ReadNegativeTime(false);
}
public void NegativeTime(bool prepared)
{
execSQL("DROP TABLE IF EXISTS Test");
execSQL(@"CREATE TABLE Test(id int, t time)");
MySqlCommand cmd = new MySqlCommand(@"INSERT INTO Test VALUES (1, @t)", conn);
cmd.Parameters.Add("@t", MySqlDbType.Time);
TimeSpan[] times = new TimeSpan[8] {
new TimeSpan(-10, 0, 0), new TimeSpan(2, -5, 10, 20),
new TimeSpan(20, -10, 10), new TimeSpan(0, -15, 25),
new TimeSpan(-4, -10, 20, -10), new TimeSpan(3, 17, 23, 6),
new TimeSpan(-1,-2,-3,-4), new TimeSpan(0,0,0,-15) };
if (prepared)
cmd.Prepare();
foreach (TimeSpan ts in times)
{
cmd.Parameters[0].Value = ts;
cmd.ExecuteNonQuery();
}
cmd.CommandText = "SELECT * FROM Test";
cmd.Parameters.Clear();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
foreach (TimeSpan ts in times)
{
reader.Read();
TimeSpan t = reader.GetTimeSpan(1);
Assert.AreEqual(ts, t);
}
}
}
private void ReadNegativeTime(bool prepared)
{
execSQL("DROP TABLE IF EXISTS Test");
execSQL("CREATE TABLE Test(id int, t time)");
execSQL("INSERT INTO Test VALUES (1, '-00:10:00')");
MySqlCommand cmd = new MySqlCommand("SELECT * FROM Test", conn);
if (prepared)
cmd.Prepare();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
TimeSpan ts = reader.GetTimeSpan(1);
Assert.AreEqual(0, ts.Hours);
Assert.AreEqual(-10, ts.Minutes);
Assert.AreEqual(0, ts.Seconds);
}
}
[Test]
public void SprocOutputParams()
{
if (Version < new Version(6, 0, 8)) return;
execSQL("CREATE PROCEDURE spTest(id INT, OUT age INT) BEGIN SET age=id; END");
MySqlCommand cmd = new MySqlCommand("spTest", conn);
cmd.Parameters.Add("@id", MySqlDbType.Int32);
cmd.Parameters.Add("@age", MySqlDbType.Int32).Direction = ParameterDirection.Output;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Prepare();
cmd.Parameters[0].Value = 20;
Assert.AreEqual(0, cmd.ExecuteNonQuery());
Assert.AreEqual(20, cmd.Parameters[1].Value);
execSQL("DROP PROCEDURE IF EXISTS spTest");
execSQL("CREATE PROCEDURE spTest(id INT, OUT age INT) BEGIN SET age=age*2; END");
cmd.Parameters[0].Value = 1;
cmd.Parameters[1].Value = 20;
Assert.AreEqual(0, cmd.ExecuteNonQuery());
Assert.AreEqual(20, cmd.Parameters[1].Value);
}
[Test]
public void SprocInputOutputParams()
{
if (Version < new Version(6, 0, 8)) return;
execSQL("CREATE PROCEDURE spTest(id INT, INOUT age INT) BEGIN SET age=age*2; END");
MySqlCommand cmd = new MySqlCommand("spTest", conn);
cmd.Parameters.Add("@id", MySqlDbType.Int32);
cmd.Parameters.Add("@age", MySqlDbType.Int32).Direction = ParameterDirection.InputOutput;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Prepare();
cmd.Parameters[0].Value = 1;
cmd.Parameters[1].Value = 20;
Assert.AreEqual(0, cmd.ExecuteNonQuery());
Assert.AreEqual(40, cmd.Parameters[1].Value);
}
/// <summary>
/// Bug #49794 MySqlDataReader.GetUInt64 doesn't work for large BIGINT UNSIGNED
/// </summary>
[Test]
public void BigIntUnsigned()
{
execSQL("DROP TABLE IF EXISTS test");
execSQL(@"CREATE TABLE test(id int(10) unsigned NOT NULL, testValue bigint(20) unsigned NOT NULL,
PRIMARY KEY USING BTREE (Id)) ENGINE=InnoDB DEFAULT CHARSET=latin1");
execSQL("INSERT INTO test(Id,TestValue) VALUES(1, 3000000000)");
MySqlCommand cmd = new MySqlCommand("SELECT testValue FROM test WHERE id=@Id", conn);
cmd.Parameters.Add("@id", MySqlDbType.UInt32);
cmd.Prepare();
cmd.Parameters["@id"].Value = 1;
using (MySqlDataReader rdr = cmd.ExecuteReader())
{
rdr.Read();
UInt64 v = rdr.GetUInt64(0);
Assert.AreEqual(3000000000, v);
}
}
}
#region Configs
#if !CF
[Category("Compressed")]
public class PreparedStatementsSocketCompressed : PreparedStatements
{
protected override string GetConnectionInfo()
{
return String.Format("port={0};compress=true", port);
}
}
[Category("Pipe")]
public class PreparedStatementsPipe : PreparedStatements
{
protected override string GetConnectionInfo()
{
return String.Format("protocol=pipe;pipe name={0}", pipeName);
}
}
[Category("Compressed")]
[Category("Pipe")]
public class PreparedStatementsPipeCompressed : PreparedStatements
{
protected override string GetConnectionInfo()
{
return String.Format("protocol=pipe;pipe name={0};compress=true", pipeName);
}
}
[Category("SharedMemory")]
public class PreparedStatementsSharedMemory : PreparedStatements
{
protected override string GetConnectionInfo()
{
return String.Format("protocol=memory; shared memory name={0}", memoryName);
}
}
[Category("Compressed")]
[Category("SharedMemory")]
public class PreparedStatementsSharedMemoryCompressed : PreparedStatements
{
protected override string GetConnectionInfo()
{
return String.Format("protocol=memory; shared memory name={0};compress=true", memoryName);
}
}
#endif
#endregion
}