Skip to content

Commit d7c608f

Browse files
kinderrypraeclarum
authored andcommitted
fix #811
add SingleQuery method and Tests add StringQuery IsNullOrEmpty
1 parent f8d8838 commit d7c608f

File tree

5 files changed

+231
-85
lines changed

5 files changed

+231
-85
lines changed

src/SQLite.cs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ void SetKey (string key)
381381
void SetKey (byte[] key)
382382
{
383383
if (key == null) throw new ArgumentNullException (nameof (key));
384-
if (key.Length != 32) throw new ArgumentException ("Key must be 32 bytes (256-bit)", nameof(key));
384+
if (key.Length != 32) throw new ArgumentException ("Key must be 32 bytes (256-bit)", nameof (key));
385385
var s = String.Join ("", key.Select (x => x.ToString ("X2")));
386386
Execute ("pragma key = \"x'" + s + "'\"");
387387
}
@@ -970,7 +970,11 @@ public T ExecuteScalar<T> (string query, params object[] args)
970970
var cmd = CreateCommand (query, args);
971971
return cmd.ExecuteQuery<T> ();
972972
}
973-
973+
public List<T> SingleQuery<T> (string query, params object[] args)
974+
{
975+
var cmd = CreateCommand (query, args);
976+
return cmd.ExcuteSingleQuery<T> ().ToList ();
977+
}
974978
/// <summary>
975979
/// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
976980
/// in the command text for each of the arguments and then executes that command.
@@ -2845,6 +2849,31 @@ protected virtual void OnInstanceCreated (object obj)
28452849
{
28462850
// Can be overridden.
28472851
}
2852+
public IEnumerable<T> ExcuteSingleQuery<T> ()
2853+
{
2854+
if (_conn.Trace) {
2855+
_conn.Tracer?.Invoke ("Executing Query: " + this);
2856+
}
2857+
var stmt = Prepare ();
2858+
try {
2859+
if (SQLite3.ColumnCount (stmt) != 1) {
2860+
throw new NotSupportedException ("Column count error");
2861+
}
2862+
while (SQLite3.Step (stmt) == SQLite3.Result.Row) {
2863+
var colType = SQLite3.ColumnType (stmt, 0);
2864+
var val = ReadCol (stmt, 0, colType, typeof (T));
2865+
if (val == null) {
2866+
yield return default (T);
2867+
}
2868+
else {
2869+
yield return (T)val;
2870+
}
2871+
}
2872+
}
2873+
finally {
2874+
Finalize (stmt);
2875+
}
2876+
}
28482877

28492878
public IEnumerable<T> ExecuteDeferredQuery<T> (TableMapping map)
28502879
{
@@ -2893,7 +2922,10 @@ public T ExecuteScalar<T> ()
28932922
var r = SQLite3.Step (stmt);
28942923
if (r == SQLite3.Result.Row) {
28952924
var colType = SQLite3.ColumnType (stmt, 0);
2896-
val = (T)ReadCol (stmt, 0, colType, typeof (T));
2925+
var colval = ReadCol (stmt, 0, colType, typeof (T));
2926+
if (colval != null) {
2927+
val = (T)colval;
2928+
}
28972929
}
28982930
else if (r == SQLite3.Result.Done) {
28992931
}
@@ -3139,18 +3171,18 @@ object ReadCol (Sqlite3Statement stmt, int index, SQLite3.ColType type, Type clr
31393171
var text = SQLite3.ColumnString (stmt, index);
31403172
return new Guid (text);
31413173
}
3142-
else if (clrType == typeof(Uri)) {
3143-
var text = SQLite3.ColumnString(stmt, index);
3144-
return new Uri(text);
3145-
}
3174+
else if (clrType == typeof(Uri)) {
3175+
var text = SQLite3.ColumnString(stmt, index);
3176+
return new Uri(text);
3177+
}
31463178
else if (clrType == typeof (StringBuilder)) {
31473179
var text = SQLite3.ColumnString (stmt, index);
31483180
return new StringBuilder (text);
31493181
}
31503182
else if (clrType == typeof(UriBuilder)) {
3151-
var text = SQLite3.ColumnString(stmt, index);
3152-
return new UriBuilder(text);
3153-
}
3183+
var text = SQLite3.ColumnString(stmt, index);
3184+
return new UriBuilder(text);
3185+
}
31543186
else {
31553187
throw new NotSupportedException ("Don't know how to read " + clrType);
31563188
}
@@ -3664,6 +3696,9 @@ private CompileResult CompileExpr (Expression expr, List<object> queryArgs)
36643696
else if (call.Method.Name == "Replace" && args.Length == 2) {
36653697
sqlCall = "(replace(" + obj.CommandText + "," + args[0].CommandText + "," + args[1].CommandText + "))";
36663698
}
3699+
else if (call.Method.Name == "IsNullOrEmpty" && args.Length == 1) {
3700+
sqlCall = "(" + args[0].CommandText + " is null or" + args[0].CommandText + " ='' )";
3701+
}
36673702
else {
36683703
sqlCall = call.Method.Name.ToLower () + "(" + string.Join (",", args.Select (a => a.CommandText).ToArray ()) + ")";
36693704
}

src/SQLiteAsync.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,24 @@ public Task<List<T>> QueryAsync<T> (string query, params object[] args)
10771077
{
10781078
return ReadAsync (conn => conn.Query<T> (query, args));
10791079
}
1080-
1080+
/// <summary>
1081+
/// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
1082+
/// in the command text for each of the arguments and then executes that command.
1083+
/// It returns single row of the result
1084+
/// </summary>
1085+
/// <param name="query">
1086+
/// The fully escaped SQL.
1087+
/// </param>
1088+
/// <param name="args">
1089+
/// Arguments to substitute for the occurences of '?' in the query.
1090+
/// </param>
1091+
/// <returns>
1092+
/// An enumerable with one result for single row returned by the query.
1093+
/// </returns>
1094+
public Task<List<T>> SingleQueryAsync<T> (string query, params object[] args)
1095+
{
1096+
return ReadAsync (conn => conn.SingleQuery<T> (query, args));
1097+
}
10811098
/// <summary>
10821099
/// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
10831100
/// in the command text for each of the arguments and then executes that command.

tests/AsyncTests.cs

Lines changed: 113 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ public class Customer
3333

3434
[MaxLength (64), Indexed]
3535
public string Email { get; set; }
36+
37+
[MaxLength (64), Indexed]
38+
public string Address { get; set; }
39+
40+
[MaxLength (64), Indexed]
41+
public string Country { get; set; }
3642
}
3743

3844
/// <summary>
@@ -172,10 +178,10 @@ SQLiteAsyncConnection GetConnection ()
172178
string path = null;
173179
return GetConnection (ref path);
174180
}
175-
181+
176182
string _path;
177183
string _connectionString;
178-
184+
179185
[SetUp]
180186
public void SetUp()
181187
{
@@ -195,7 +201,7 @@ public void SetUp()
195201
System.IO.File.Delete (_path);
196202
#endif
197203
}
198-
204+
199205
SQLiteAsyncConnection GetConnection (ref string path)
200206
{
201207
path = _path;
@@ -220,12 +226,14 @@ public void TestDropTableAsync ()
220226
}
221227
}
222228

223-
private Customer CreateCustomer ()
229+
private Customer CreateCustomer (string address = null, string country = null)
224230
{
225231
Customer customer = new Customer () {
226232
FirstName = "foo",
227233
LastName = "bar",
228-
Email = Guid.NewGuid ().ToString ()
234+
Email = Guid.NewGuid ().ToString (),
235+
Address = address,
236+
Country = country
229237
};
230238
return customer;
231239
}
@@ -335,7 +343,7 @@ public void GetAsync ()
335343
// check...
336344
Assert.AreEqual (customer.Id, loaded.Id);
337345
}
338-
346+
339347
[Test]
340348
public void FindAsyncWithExpression ()
341349
{
@@ -362,7 +370,7 @@ public void FindAsyncWithExpression ()
362370
// check...
363371
Assert.AreEqual (customer.Id, loaded.Id);
364372
}
365-
373+
366374
[Test]
367375
public void FindAsyncWithExpressionNull ()
368376
{
@@ -446,7 +454,56 @@ public void TestQueryAsync ()
446454
Assert.AreEqual (1, loaded.Count);
447455
Assert.AreEqual (customers[2].Email, loaded[0].Email);
448456
}
457+
[Test]
458+
public void TestSingleQueryAsync ()
459+
{
460+
// connect...
461+
var conn = GetConnection ();
462+
conn.CreateTableAsync<Customer> ().Wait ();
463+
464+
// insert some...
465+
List<Customer> customers = new List<Customer> ();
466+
for (int index = 0; index < 5; index++) {
467+
Customer customer = CreateCustomer ();
468+
469+
// insert...
470+
conn.InsertAsync (customer).Wait ();
471+
472+
// add...
473+
customers.Add (customer);
474+
}
475+
476+
// return the third one...
477+
var task = conn.SingleQueryAsync<string> ("select Email from customer where id=?", customers[2].Id);
478+
task.Wait ();
479+
var loaded = task.Result;
480+
481+
// check...
482+
Assert.AreEqual (1, loaded.Count);
483+
Assert.AreEqual (customers[2].Email, loaded[0]);
484+
485+
// return the third one...
486+
var inttest = conn.SingleQueryAsync<int> ("select Id from customer where id=?", customers[2].Id);
487+
task.Wait ();
488+
var intloaded = inttest.Result;
489+
490+
// check...
491+
Assert.AreEqual (1, loaded.Count);
492+
Assert.AreEqual (customers[2].Id, intloaded[0]);
493+
494+
// return string list
495+
var listtask = conn.SingleQueryAsync<string> ("select Email from customer order by Id");
496+
listtask.Wait ();
497+
var listloaded = listtask.Result;
449498

499+
// check...
500+
Assert.AreEqual (5, listloaded.Count);
501+
Assert.AreEqual (customers[2].Email, listloaded[2]);
502+
503+
// select columns
504+
var columnstask= conn.SingleQueryAsync<string> ("select * from customer");
505+
ExceptionAssert.Throws<AggregateException> (() => columnstask.Wait ());
506+
}
450507
[Test]
451508
public void TestTableAsync ()
452509
{
@@ -577,10 +634,16 @@ public void TestExecuteScalar ()
577634
conn.CreateTableAsync<Customer> ().Wait ();
578635

579636
// check...
580-
var task = conn.ExecuteScalarAsync<object> ("select name from sqlite_master where type='table' and name='customer'");
637+
var task = conn.ExecuteScalarAsync<object>("select name from sqlite_master where type='table' and name='customer'");
581638
task.Wait ();
582639
object name = task.Result;
583640
Assert.AreNotEqual ("Customer", name);
641+
//delete
642+
conn.DeleteAllAsync<Customer>().Wait();
643+
// check...
644+
var nodatatask = conn.ExecuteScalarAsync<int> ("select Max(Id) from sqlite_master where type='table' and name='customer'");
645+
task.Wait ();
646+
Assert.AreNotEqual (0, nodatatask.Result);
584647
}
585648

586649
[Test]
@@ -687,18 +750,31 @@ public void TestAsyncTableQueryWhereOperation ()
687750
conn.CreateTableAsync<Customer> ().Wait ();
688751

689752
// create...
690-
Customer customer = this.CreateCustomer ();
691-
conn.InsertAsync (customer).Wait ();
692-
753+
Customer customer1 = this.CreateCustomer(string.Empty, "country");
754+
conn.InsertAsync (customer1).Wait ();
755+
Customer customer2 = this.CreateCustomer("address");
756+
conn.InsertAsync(customer1).Wait();
693757
// query...
694-
var query = conn.Table<Customer> ();
695-
var task = query.ToListAsync ();
758+
var query = conn.Table<Customer>();
759+
var task = query.ToListAsync();
696760
task.Wait ();
697761
var items = task.Result;
698762

699763
// check...
700-
var loaded = items.Where (v => v.Id == customer.Id).First ();
701-
Assert.AreEqual (customer.Email, loaded.Email);
764+
var loaded = items.Where(v => v.Id == customer1.Id).First();
765+
Assert.AreEqual(customer1.Email, loaded.Email);
766+
767+
// check...
768+
var emptyaddress = items.Where(v => string.IsNullOrEmpty(v.Address)).First();
769+
Assert.AreEqual(customer1.Email, emptyaddress.Email);
770+
771+
// check...
772+
var nullcountry = items.Where (v => string.IsNullOrEmpty (v.Country)).First ();
773+
Assert.AreEqual (customer2.Email, emptyaddress.Email);
774+
775+
// check...
776+
var isnotnullorempty = items.Where (v => !string.IsNullOrEmpty (v.Country)).First ();
777+
Assert.AreEqual (customer1.Email, emptyaddress.Email);
702778
}
703779

704780
[Test]
@@ -838,28 +914,28 @@ public void TestAsyncTableElementAtAsync ()
838914
}
839915

840916

841-
[Test]
842-
public void TestAsyncGetWithExpression()
843-
{
844-
var conn = GetConnection();
845-
conn.CreateTableAsync<Customer>().Wait();
846-
conn.ExecuteAsync("delete from customer").Wait();
847-
848-
// create...
849-
for (int index = 0; index < 10; index++)
850-
{
851-
var customer = this.CreateCustomer();
852-
customer.FirstName = index.ToString();
853-
conn.InsertAsync(customer).Wait();
854-
}
855-
856-
// get...
857-
var result = conn.GetAsync<Customer>(x => x.FirstName == "7");
858-
result.Wait();
859-
var loaded = result.Result;
860-
// check...
861-
Assert.AreEqual("7", loaded.FirstName);
862-
}
917+
[Test]
918+
public void TestAsyncGetWithExpression()
919+
{
920+
var conn = GetConnection();
921+
conn.CreateTableAsync<Customer>().Wait();
922+
conn.ExecuteAsync("delete from customer").Wait();
923+
924+
// create...
925+
for (int index = 0; index < 10; index++)
926+
{
927+
var customer = this.CreateCustomer();
928+
customer.FirstName = index.ToString();
929+
conn.InsertAsync(customer).Wait();
930+
}
931+
932+
// get...
933+
var result = conn.GetAsync<Customer>(x => x.FirstName == "7");
934+
result.Wait();
935+
var loaded = result.Result;
936+
// check...
937+
Assert.AreEqual("7", loaded.FirstName);
938+
}
863939

864940
[Test]
865941
public void CreateTable ()

tests/ScalarTest.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ SQLiteConnection CreateDb ()
2929
var db = new TestDb ();
3030
db.CreateTable<TestTable> ();
3131
var items = from i in Enumerable.Range (0, Count)
32-
select new TestTable { Two = 2 };
32+
select new TestTable { Two = 2 };
3333
db.InsertAll (items);
3434
Assert.AreEqual (Count, db.Table<TestTable> ().Count ());
3535
return db;
@@ -40,10 +40,16 @@ SQLiteConnection CreateDb ()
4040
public void Int32 ()
4141
{
4242
var db = CreateDb ();
43-
43+
4444
var r = db.ExecuteScalar<int> ("SELECT SUM(Two) FROM TestTable");
4545

4646
Assert.AreEqual (Count * 2, r);
47+
48+
db.DeleteAll<TestTable> ();
49+
50+
var r1 = db.ExecuteScalar<int> ("SELECT SUM(Two) FROM TestTable");
51+
52+
Assert.AreEqual (0, r1);
4753
}
4854

4955
[Test]

0 commit comments

Comments
 (0)