Skip to content

Commit

Permalink
Improved Timestamp handling. 1000 upsert unit test.
Browse files Browse the repository at this point in the history
  • Loading branch information
dwdii committed Aug 3, 2016
1 parent 4009726 commit 78e1910
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 12 deletions.
164 changes: 158 additions & 6 deletions Garuda.Data.Test/PhoenixUnitTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data;
using System.Collections.Generic;
using System.Text;

namespace Garuda.Data.Test
{
Expand Down Expand Up @@ -260,7 +261,66 @@ public void CommandPrepareWith1String1FloatParamsTest()
pFuncs);
}

private void PreparedCmdParameterTest(int rowsToInsert, string sql, List<Func<object>> pFunc)
[TestMethod]
public void CommandPrepareWithParamsStringIntUintUlongShortFloatTest()
{
int rowsToInsert = 10;
List<Func<object>> pFuncs = new List<Func<object>>();
pFuncs.Add(() => string.Format("N{0}", DateTime.Now.ToString("hmmss")));
pFuncs.Add(() => DateTime.Now.Millisecond);
pFuncs.Add(() => Convert.ToUInt32(DateTime.Now.Millisecond));
pFuncs.Add(() => Convert.ToUInt64(DateTime.Now.Ticks));
pFuncs.Add(() => Convert.ToInt16(DateTime.Now.Second));
pFuncs.Add(() => Convert.ToSingle(0.2 / 0.14));

PreparedCmdParameterTest(rowsToInsert,
"UPSERT INTO GARUDATEST (ID, AircraftIcaoNumber, MyInt, MyUint, MyUlong, MyTingInt, MyTime, MyDate, MyTimestamp, MyUnsignedTime, MyFloat) VALUES (NEXT VALUE FOR garuda.testsequence, :1, :2, :3, :4, :5, CURRENT_TIME(), CURRENT_DATE(), '2016-07-25 22:28:00', CURRENT_TIME(), :6)",
pFuncs);
}

[TestMethod]
public void ExecuteNonQueryUpsert1KBigTable()
{
int rowsToInsert = 1000;
List<Func<object>> pFuncs = new List<Func<object>>();
pFuncs.Add(() => string.Format("N{0}", DateTime.Now.ToString("hmmss")));
pFuncs.Add(() => Guid.NewGuid().ToString());
pFuncs.Add(() => DateTime.Now);

using (IDbConnection c = new PhoenixConnection())
{
c.ConnectionString = this.ConnectionString();
c.Open();
CreateBigTestTableIfNotExists(c, false);
}

PreparedCmdParameterTest(rowsToInsert,
"UPSERT INTO bigtable (ID, AircraftIcaoNumber, LruFlightKey, MyTimestamp) VALUES (NEXT VALUE FOR garuda.bigtableSequence, :1, :2, :3)",
pFuncs, false);
}

[TestMethod]
public void ExecuteQueryBigTable()
{
using (IDbConnection c = new PhoenixConnection())
{
c.ConnectionString = this.ConnectionString();
c.Open();

CreateBigTestTableIfNotExists(c, false);

// Query the table
long rows = QueryAllRows(c, "bigtable", 10);

// How many rows did we get back?
this.TestContext.WriteLine("Queried Rows: {0}", rows);

// More than zero?
Assert.IsTrue(rows > 0);
}
}

private void PreparedCmdParameterTest(int rowsToInsert, string sql, List<Func<object>> pFunc, bool assertTotalRows = true)
{
using (IDbConnection c = new PhoenixConnection())
{
Expand Down Expand Up @@ -296,30 +356,67 @@ private void PreparedCmdParameterTest(int rowsToInsert, string sql, List<Func<ob
tx.Commit();
}

Assert.AreEqual(rowsToInsert, QueryAllRows(c));
if(assertTotalRows)
{
Assert.AreEqual(rowsToInsert, QueryAllRows(c));
}

}
}

private long QueryAllRows(IDbConnection c)
{
return QueryAllRows(c, "GARUDATEST", int.MaxValue);
}

private long QueryAllRows(IDbConnection c, string table, int logResults)
{
long recCount = 0;
object oVal = null;
StringBuilder line = new StringBuilder();

// Query for data... should get one rows.
using (IDbCommand cmd = c.CreateCommand())
{
cmd.CommandText = "SELECT * FROM GARUDATEST";
cmd.CommandText = string.Format("SELECT * FROM {0}", table);
using (IDataReader reader = cmd.ExecuteReader())
{
#region Log Column Headers
if (logResults > 0)
{
for (int i = 0; i < reader.FieldCount; i++)
{
if(i > 0)
{
line.Append(",");
}
line.AppendFormat("{0} ({1})", reader.GetName(i), reader.GetDataTypeName(i));
}
this.TestContext.WriteLine(line.ToString());
line.Clear();
}
#endregion

while (reader.Read())
{
recCount++;

for(int i = 0; i < reader.FieldCount; i++)
#region Log Column Row
if (logResults > recCount)
{
oVal = reader.GetValue(i);
this.TestContext.WriteLine(string.Format("{0}: {1} ({2})", reader.GetName(i), oVal, reader.GetDataTypeName(i)));
for (int i = 0; i < reader.FieldCount; i++)
{
if (i > 0)
{
line.Append(",");
}
line.Append(reader.GetValue(i));
}
this.TestContext.WriteLine(line.ToString());
line.Clear();
}
#endregion

}
}
}
Expand Down Expand Up @@ -370,6 +467,61 @@ private static void ReCreateTestTableIfNotExists(IDbConnection phConn)
}
}

private static void CreateBigTestTableIfNotExists(IDbConnection phConn, bool dropIfExists)
{
ReCreateTestTableIfNotExists(phConn, "bigtable",
"CREATE TABLE IF NOT EXISTS bigtable (ID BIGINT PRIMARY KEY, AircraftIcaoNumber varchar(16), LruFlightKey varchar(64), MyTimestamp TIMESTAMP )",
true, dropIfExists);
}

private static void ReCreateTestTableIfNotExists(IDbConnection phConn, string table, string createStmt, bool createSequence, bool dropIfExists)
{
if(dropIfExists)
{
using (IDbCommand cmd = phConn.CreateCommand())
{
cmd.CommandText = string.Format("DROP TABLE IF EXISTS {0}", table);
cmd.ExecuteNonQuery();
}
}


using (IDbCommand cmd = phConn.CreateCommand())
{
cmd.CommandText = createStmt;
cmd.ExecuteNonQuery();
}

bool bCreateSequence = true;
string seqName = string.Format("{0}Sequence", table);
using (IDbCommand cmd = phConn.CreateCommand())
{

cmd.CommandText = "SELECT sequence_schema, sequence_name, start_with, increment_by, cache_size FROM SYSTEM.\"SEQUENCE\""; // WHERE sequence_schema = 'garuda' AND sequence_name='testsequence'
using (IDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
if (reader.GetString(1).Equals(seqName, StringComparison.InvariantCultureIgnoreCase))
{
bCreateSequence = false;
break;
}

}
}
}

if (bCreateSequence)
{
using (IDbCommand cmd = phConn.CreateCommand())
{
cmd.CommandText = string.Format("CREATE SEQUENCE garuda.{0}", seqName);
cmd.ExecuteNonQuery();
}
}
}

private string ConnectionString()
{
return System.IO.File.ReadAllText(@"..\..\..\GarudaUtil\myconnection.txt");
Expand Down
3 changes: 3 additions & 0 deletions Garuda.Data/Garuda.Data.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@
<dependency id="EnterpriseLibrary.TransientFaultHandling" version="6.0.1304" />
</dependencies>
</metadata>
<files>
<file src="bin\$configuration$\Garuda.Data.xml" target="lib\Net452" />
</files>
</package>
17 changes: 12 additions & 5 deletions Garuda.Data/PhoenixDataReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ public override object GetValue(int ordinal)
case "TIME":
o = FromPhoenixTime(val.NumberValue);
break;

case "TIMESTAMP":
o = FromPhoenixTimestamp(val.NumberValue);
break;
}

return o;
Expand Down Expand Up @@ -361,15 +365,18 @@ private TypedValue CurrentRowValue(int ordinal)

private TimeSpan FromPhoenixTime(long time)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var dtTime = epoch.AddMilliseconds(time);
return dtTime.Subtract(epoch);
var dtTime = PhoenixParameter.Constants.Epoch.AddMilliseconds(time);
return dtTime.Subtract(PhoenixParameter.Constants.Epoch);
}

private DateTime FromPhoenixDate(long date)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddDays(date);
return PhoenixParameter.Constants.Epoch.AddDays(date);
}

private DateTime FromPhoenixTimestamp(long timestamp)
{
return PhoenixParameter.Constants.Epoch.AddMilliseconds(timestamp);
}
}
}
59 changes: 58 additions & 1 deletion Garuda.Data/PhoenixParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,69 @@

namespace Garuda.Data
{
/// <summary>
/// Encapsulates a parameter for a Phoenix command.
/// </summary>
public class PhoenixParameter : System.Data.Common.DbParameter
{
public struct Constants
{
public static string TimestampFormat = "yyyy-MM-dd hh:mm:ss.fffffff";

public static DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
}

/// <summary>
/// Creates a new instance of a Phoenix parameter with the specified value.
/// </summary>
public PhoenixParameter()
{
}

/// <summary>
/// Creates a new instance of a Phoenix parameter with the specified value.
/// </summary>
/// <param name="value"></param>
public PhoenixParameter(object value)
{
this.Value = value;
}

/// <summary>
/// Gets or sets the DbType of the parameter.
/// </summary>
public override DbType DbType { get; set; }

/// <summary>
/// Gets or sets a value indicating whether the parameter is input-only, output-only, bidirectional, or a stored procedure return value parameter.
/// </summary>
public override ParameterDirection Direction { get; set; }

/// <summary>
/// Gets a value indicating whether the parameter accepts null values.
/// </summary>
public override bool IsNullable { get; set; }

/// <summary>
/// Gets or sets the name of the IDataParameter.
/// </summary>
public override string ParameterName { get; set; }

/// <summary>
/// The size of the parameter.
/// </summary>
public override int Size { get; set; }

/// <summary>
/// Gets or sets the name of the source column that is mapped to the DataSet and used for loading or returning the Value.
/// </summary>
public override string SourceColumn { get; set; }

public override bool SourceColumnNullMapping { get; set; }

/// <summary>
/// Gets or sets the value of the parameter.
/// </summary>
public override object Value { get; set; }

public override void ResetDbType()
Expand All @@ -47,7 +94,12 @@ public TypedValue AsPhoenixTypedValue()
else
{
Type pt = this.Value.GetType();
if (pt == typeof(int) || pt == typeof(long))
if (pt == typeof(int) ||
pt == typeof(long) ||
pt == typeof(uint) ||
pt == typeof(ulong) ||
pt == typeof(short) ||
pt == typeof(ushort))
{
tv.NumberValue = Convert.ToInt64(this.Value);
tv.Type = Rep.LONG;
Expand All @@ -62,6 +114,11 @@ public TypedValue AsPhoenixTypedValue()
tv.StringValue = Convert.ToString(this.Value);
tv.Type = Rep.STRING;
}
else if(pt == typeof(DateTime))
{
tv.NumberValue = Convert.ToInt64(Convert.ToDateTime(this.Value).Subtract(PhoenixParameter.Constants.Epoch).TotalMilliseconds);
tv.Type = Rep.JAVA_SQL_TIMESTAMP;
}
else if (this.Value == DBNull.Value)
{
tv.Null = true;
Expand Down

0 comments on commit 78e1910

Please sign in to comment.