PageRenderTime 65ms CodeModel.GetById 2ms app.highlight 56ms RepoModel.GetById 2ms app.codeStats 0ms

/PetaPoco.Tests/Tests.cs

http://github.com/toptensoftware/PetaPoco
C# | 883 lines | 639 code | 155 blank | 89 comment | 9 complexity | 64f22d471a2eaa2972dd01406903e9ec MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5using PetaTest;
  6using PetaPoco;
  7
  8namespace PetaPoco.Tests
  9{
 10	[TestFixture("sqlserver")]
 11	[TestFixture("sqlserverce")]
 12	[TestFixture("mysql")]
 13	[TestFixture("postgresql")]
 14	public class Tests
 15	{
 16		public Tests(string connectionStringName)
 17		{
 18			_connectionStringName = connectionStringName;
 19		}
 20
 21		string _connectionStringName;
 22		Random r = new Random();
 23		Database db;
 24
 25		[TestFixtureSetUp]
 26		public void CreateDB()
 27		{
 28			db = new Database(_connectionStringName);
 29			db.OpenSharedConnection();		// <-- Wow, this is crucial to getting SqlCE to perform.
 30			db.Execute(Utils.LoadTextResource(string.Format("PetaPoco.Tests.{0}_init.sql", _connectionStringName)));
 31		}
 32
 33		[TestFixtureTearDown]
 34		public void DeleteDB()
 35		{
 36			db.Execute(Utils.LoadTextResource(string.Format("PetaPoco.Tests.{0}_done.sql", _connectionStringName)));
 37		}
 38
 39		long GetRecordCount()
 40		{
 41			return db.ExecuteScalar<long>("SELECT COUNT(*) FROM petapoco");
 42		}
 43
 44		[TearDown]
 45		public void Teardown()
 46		{
 47			// Delete everything
 48			db.Delete<deco>("");
 49			db.Delete<petapoco2>("");
 50
 51			// Should be clean
 52			Assert.AreEqual(GetRecordCount(), 0);
 53		}
 54
 55		poco CreatePoco()
 56		{
 57			// Need a rounded date as DB can't store millis
 58			var now = DateTime.UtcNow;
 59			now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
 60
 61			// Setup a record
 62			var o = new poco();
 63			o.title = string.Format("insert {0}", r.Next());
 64			o.draft = true;
 65			o.content = string.Format("insert {0}", r.Next());
 66			o.date_created = now;
 67			o.date_edited = now;
 68			o.state = State.Yes;
 69			o.col_w_space = 23;
 70			o.nullreal = 24;
 71
 72			return o;
 73		}
 74
 75		deco CreateDeco()
 76		{
 77			// Need a rounded date as DB can't store millis
 78			var now = DateTime.UtcNow;
 79			now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
 80
 81			// Setup a record
 82			var o = new deco();
 83			o.title = string.Format("insert {0}", r.Next());
 84			o.draft = true;
 85			o.content = string.Format("insert {0}", r.Next());
 86			o.date_created = now;
 87			o.date_edited = now;
 88			o.state = State.Maybe;
 89			o.col_w_space = 23;
 90			o.nullreal = 24;
 91
 92			return o;
 93		}
 94
 95		void AssertPocos(poco a, poco b)
 96		{
 97			Assert.AreEqual(a.id, b.id);
 98			Assert.AreEqual(a.title, b.title);
 99			Assert.AreEqual(a.draft, b.draft);
100			Assert.AreEqual(a.content, b.content);
101			Assert.AreEqual(a.date_created, b.date_created);
102			Assert.AreEqual(a.date_edited, b.date_edited);
103			Assert.AreEqual(a.state, b.state);
104			Assert.AreEqual(a.col_w_space, b.col_w_space);
105			Assert.AreEqual(a.nullreal, b.nullreal);
106		}
107
108		void AssertPocos(deco a, deco b)
109		{
110			Assert.AreEqual(a.id, b.id);
111			Assert.AreEqual(a.title, b.title);
112			Assert.AreEqual(a.draft, b.draft);
113			Assert.AreEqual(a.content, b.content);
114			Assert.AreEqual(a.date_created, b.date_created);
115			Assert.AreEqual(a.state, b.state);
116			Assert.AreEqual(a.col_w_space, b.col_w_space);
117			Assert.AreEqual(a.nullreal, b.nullreal);
118		}
119
120		// Insert some records, return the id of the first
121		long InsertRecords(int count)
122		{
123			long lFirst = 0;
124			for (int i = 0; i < count; i++)
125			{
126				var o=CreatePoco();
127				db.Insert("petapoco", "id", o);
128
129				var lc = db.LastCommand;
130
131				if (i == 0)
132				{
133					lFirst = o.id;
134					Assert.AreNotEqual(o.id, 0);
135				}
136			}
137
138			return lFirst;
139		}
140
141		[Test]
142		public void poco_Crud()
143		{
144			// Create a random record
145			var o = CreatePoco();
146
147			Assert.IsTrue(db.IsNew("id", o));
148
149			// Insert it
150			db.Insert("petapoco", "id", o);
151			Assert.AreNotEqual(o.id, 0);
152
153			Assert.IsFalse(db.IsNew("id", o));
154
155			// Retrieve it
156			var o2 = db.Single<poco>("SELECT * FROM petapoco WHERE id=@0", o.id);
157
158			Assert.IsFalse(db.IsNew("id", o2));
159
160			// Check it
161			AssertPocos(o, o2);
162
163			// Update it
164			o2.title = "New Title";
165			db.Save("petapoco", "id", o2);
166
167			// Retrieve itagain
168			var o3 = db.Single<poco>("SELECT * FROM petapoco WHERE id=@0", o.id);
169
170			// Check it
171			AssertPocos(o2, o3);
172
173			// Delete it
174			db.Delete("petapoco", "id", o3);
175
176			// Should be gone!
177			var o4 = db.SingleOrDefault<poco>("SELECT * FROM petapoco WHERE id=@0", o.id);
178			Assert.IsNull(o4);
179		}
180
181		[Test]
182		public void deco_Crud()
183		{
184			// Create a random record
185			var o = CreateDeco();
186			Assert.IsTrue(db.IsNew(o));
187
188			// Insert it
189			db.Insert(o);
190			Assert.AreNotEqual(o.id, 0);
191
192			Assert.IsFalse(db.IsNew(o));
193			
194			// Retrieve it
195			var o2 = db.Single<deco>("SELECT * FROM petapoco WHERE id=@0", o.id);
196
197			Assert.IsFalse(db.IsNew(o2));
198
199			// Check it
200			AssertPocos(o, o2);
201
202			// Update it
203			o2.title = "New Title";
204			db.Save(o2);
205
206			// Retrieve itagain
207			var o3 = db.Single<deco>("SELECT * FROM petapoco WHERE id=@0", o.id);
208
209			// Check it
210			AssertPocos(o2, o3);
211
212			// Delete it
213			db.Delete(o3);
214
215			// Should be gone!
216			var o4 = db.SingleOrDefault<deco>("SELECT * FROM petapoco WHERE id=@0", o.id);
217			Assert.IsNull(o4);
218		}
219
220		[Test]
221		public void Fetch()
222		{
223			// Create some records
224			const int count = 5;
225			long id = InsertRecords(count);
226
227			// Fetch em
228			var r = db.Fetch<poco>("SELECT * from petapoco ORDER BY id");
229			Assert.AreEqual(r.Count, count);
230
231			// Check em
232			for (int i = 0; i < count; i++)
233			{
234				Assert.AreEqual(r[i].id, id + i);
235			}
236
237		}
238
239		[Test]
240		public void Query()
241		{
242			// Create some records
243			const int count = 5;
244			long id = InsertRecords(count);
245
246			// Fetch em
247			var r = db.Query<poco>("SELECT * from petapoco ORDER BY id");
248
249			// Check em
250			int i = 0;
251			foreach (var p in r)
252			{
253				Assert.AreEqual(p.id, id + i);
254				i++;
255			}
256			Assert.AreEqual(i, count);
257		}
258
259		[Test]
260		public void Page()
261		{
262			// In this test we're checking that the page count is correct when there are
263			// not-exactly pagesize*N records (ie: a partial page at the end)
264
265			// Create some records
266			const int count = 13;
267			long id = InsertRecords(count);
268
269			// Fetch em
270			var r = db.Page<poco>(2, 5, "SELECT * from petapoco ORDER BY id");
271
272			// Check em
273			int i = 0;
274			foreach (var p in r.Items)
275			{
276				Assert.AreEqual(p.id, id + i + 5);
277				i++;
278			}
279
280			// Check other stats
281			Assert.AreEqual(r.Items.Count, 5);
282			Assert.AreEqual(r.CurrentPage, 2);
283			Assert.AreEqual(r.ItemsPerPage, 5);
284			Assert.AreEqual(r.TotalItems, 13);
285			Assert.AreEqual(r.TotalPages, 3);
286		}
287
288		[Test]
289		public void Page_NoOrderBy()
290		{
291			// Unordered paging not supported by Compact Edition
292			if (_connectionStringName == "sqlserverce")
293				return;
294			// In this test we're checking that the page count is correct when there are
295			// not-exactly pagesize*N records (ie: a partial page at the end)
296
297			// Create some records
298			const int count = 13;
299			long id = InsertRecords(count);
300
301			// Fetch em
302			var r = db.Page<poco>(2, 5, "SELECT * from petapoco");
303
304			// Check em
305			int i = 0;
306			foreach (var p in r.Items)
307			{
308				Assert.AreEqual(p.id, id + i + 5);
309				i++;
310			}
311
312			// Check other stats
313			Assert.AreEqual(r.Items.Count, 5);
314			Assert.AreEqual(r.CurrentPage, 2);
315			Assert.AreEqual(r.ItemsPerPage, 5);
316			Assert.AreEqual(r.TotalItems, 13);
317			Assert.AreEqual(r.TotalPages, 3);
318		}
319
320		[Test]
321		public void Page_Distinct()
322		{
323			// Unordered paging not supported by Compact Edition
324			if (_connectionStringName == "sqlserverce")
325				return;
326			// In this test we're checking that the page count is correct when there are
327			// not-exactly pagesize*N records (ie: a partial page at the end)
328
329			// Create some records
330			const int count = 13;
331			long id = InsertRecords(count);
332
333			// Fetch em
334			var r = db.Page<poco>(2, 5, "SELECT DISTINCT id from petapoco ORDER BY id");
335
336			// Check em
337			int i = 0;
338			foreach (var p in r.Items)
339			{
340				Assert.AreEqual(p.id, id + i + 5);
341				i++;
342			}
343
344			// Check other stats
345			Assert.AreEqual(r.Items.Count, 5);
346			Assert.AreEqual(r.CurrentPage, 2);
347			Assert.AreEqual(r.ItemsPerPage, 5);
348			Assert.AreEqual(r.TotalItems, 13);
349			Assert.AreEqual(r.TotalPages, 3);
350		}
351
352		[Test]
353		public void FetchPage()
354		{
355			// Create some records
356			const int count = 13;
357			long id = InsertRecords(count);
358
359			// Fetch em
360			var r = db.Fetch<poco>(2, 5, "SELECT * from petapoco ORDER BY id");
361
362			// Check em
363			int i = 0;
364			foreach (var p in r)
365			{
366				Assert.AreEqual(p.id, id + i + 5);
367				i++;
368			}
369
370			// Check other stats
371			Assert.AreEqual(r.Count, 5);
372		}
373
374		[Test]
375		public void Page_boundary()
376		{
377			// In this test we're checking that the page count is correct when there are
378			// exactly pagesize*N records.
379
380			// Create some records
381			const int count = 15;
382			long id = InsertRecords(count);
383
384			// Fetch em
385			var r = db.Page<poco>(3, 5, "SELECT * from petapoco ORDER BY id");
386
387			// Check other stats
388			Assert.AreEqual(r.Items.Count, 5);
389			Assert.AreEqual(r.CurrentPage, 3);
390			Assert.AreEqual(r.ItemsPerPage, 5);
391			Assert.AreEqual(r.TotalItems, 15);
392			Assert.AreEqual(r.TotalPages, 3);
393		}
394
395		[Test]
396		public void deco_Delete()
397		{
398			// Create some records
399			const int count = 15;
400			long id = InsertRecords(count);
401
402			// Delete some
403			db.Delete<deco>("WHERE id>=@0", id + 5);
404
405			// Check they match
406			Assert.AreEqual(GetRecordCount(), 5);
407		}
408
409		[Test]
410		public void deco_Update()
411		{
412			// Create some records
413			const int count = 15;
414			long id = InsertRecords(count);
415
416			// Update some
417			db.Update<deco>("SET title=@0 WHERE id>=@1", "zap", id + 5);
418
419			// Check some updated
420			foreach (var d in db.Query<deco>("ORDER BY Id"))
421			{
422				if (d.id >= id + 5)
423				{
424					Assert.AreEqual(d.title, "zap");
425				}
426				else
427				{
428					Assert.AreNotEqual(d.title, "zap");
429				}
430			}
431		}
432
433		[Test]
434		public void deco_ExplicitAttribute()
435		{
436			// Create a records
437			long id = InsertRecords(1);
438
439			// Retrieve it in two different ways
440			var a = db.SingleOrDefault<deco>("WHERE id=@0", id);
441			var b = db.SingleOrDefault<deco_explicit>("WHERE id=@0", id);
442			var c = db.SingleOrDefault<deco_explicit>("SELECT * FROM petapoco WHERE id=@0", id);
443
444			// b record should have ignored the content
445			Assert.IsNotNull(a.content);
446			Assert.IsNull(b.content);
447			Assert.IsNull(c.content);
448		}
449
450
451		[Test]
452		public void deco_IgnoreAttribute()
453		{
454			// Create a records
455			long id = InsertRecords(1);
456
457			// Retrieve it in two different ways
458			var a = db.SingleOrDefault<deco>("WHERE id=@0", id);
459			var b = db.SingleOrDefault<deco_non_explicit>("WHERE id=@0", id);
460			var c = db.SingleOrDefault<deco_non_explicit>("SELECT * FROM petapoco WHERE id=@0", id);
461
462			// b record should have ignored the content
463			Assert.IsNotNull(a.content);
464			Assert.IsNull(b.content);
465			Assert.IsNull(c.content);
466		}
467
468		[Test]
469		public void Transaction_complete()
470		{
471			using (var scope = db.GetTransaction())
472			{
473				InsertRecords(10);
474				scope.Complete();
475			}
476
477			Assert.AreEqual(GetRecordCount(), 10);
478		}
479
480		[Test]
481		public void Transaction_cancelled()
482		{
483			using (var scope = db.GetTransaction())
484			{
485				InsertRecords(10);
486			}
487
488			Assert.AreEqual(GetRecordCount(), 0);
489		}
490
491		[Test]
492		public void Transaction_nested_nn()
493		{
494			using (var scope1 = db.GetTransaction())
495			{
496				InsertRecords(10);
497
498				using (var scope2 = db.GetTransaction())
499				{
500					InsertRecords(10);
501				}
502			}
503
504			Assert.AreEqual(GetRecordCount(), 0);
505		}
506
507		[Test]
508		public void Transaction_nested_yn()
509		{
510			using (var scope1 = db.GetTransaction())
511			{
512				InsertRecords(10);
513
514				using (var scope2 = db.GetTransaction())
515				{
516					InsertRecords(10);
517				}
518				scope1.Complete();
519			}
520
521			Assert.AreEqual(GetRecordCount(), 0);
522		}
523
524		[Test]
525		public void Transaction_nested_ny()
526		{
527			using (var scope1 = db.GetTransaction())
528			{
529				InsertRecords(10);
530
531				using (var scope2 = db.GetTransaction())
532				{
533					InsertRecords(10);
534					scope2.Complete();
535				}
536			}
537
538			Assert.AreEqual(GetRecordCount(), 0);
539		}
540
541		[Test]
542		public void Transaction_nested_yy()
543		{
544			using (var scope1 = db.GetTransaction())
545			{
546				InsertRecords(10);
547
548				using (var scope2 = db.GetTransaction())
549				{
550					InsertRecords(10);
551					scope2.Complete();
552				}
553
554				scope1.Complete();
555			}
556
557			Assert.AreEqual(GetRecordCount(), 20);
558		}
559
560		[Test]
561		public void Transaction_nested_yny()
562		{
563			using (var scope1 = db.GetTransaction())
564			{
565				InsertRecords(10);
566
567				using (var scope2 = db.GetTransaction())
568				{
569					InsertRecords(10);
570					//scope2.Complete();
571				}
572
573				using (var scope3 = db.GetTransaction())
574				{
575					InsertRecords(10);
576					scope3.Complete();
577				}
578
579				scope1.Complete();
580			}
581
582			Assert.AreEqual(GetRecordCount(), 0);
583		}
584
585		[Test]
586		public void DateTimesAreUtc()
587		{
588			var id = InsertRecords(1);
589			var a2 = db.SingleOrDefault<deco>("WHERE id=@0", id);
590			Assert.AreEqual(a2.date_created.Kind, DateTimeKind.Utc);
591			Assert.AreEqual(a2.date_edited.Value.Kind, DateTimeKind.Utc);
592		}
593
594		[Test]
595		public void DateTimeNullable()
596		{
597			// Need a rounded date as DB can't store millis
598			var now = DateTime.UtcNow;
599			now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
600
601			// Setup a record
602			var a = new deco();
603			a.title = string.Format("insert {0}", r.Next());
604			a.draft = true;
605			a.content = string.Format("insert {0}", r.Next());
606			a.date_created = now;
607			a.date_edited = null;
608
609			db.Insert(a);
610
611			// Retrieve it
612			var b = db.SingleOrDefault<deco>("WHERE id=@0", a.id);
613			Assert.AreEqual(b.id, a.id);
614			Assert.AreEqual(b.date_edited.HasValue, false);
615
616			// Update it to NULL
617			b.date_edited = now;
618			db.Update(b);
619			var c = db.SingleOrDefault<deco>("WHERE id=@0", a.id);
620			Assert.AreEqual(c.id, a.id);
621			Assert.AreEqual(c.date_edited.HasValue, true);
622
623			// Update it to not NULL
624			c.date_edited = null;
625			db.Update(c);
626			var d = db.SingleOrDefault<deco>("WHERE id=@0", a.id);
627			Assert.AreEqual(d.id, a.id);
628			Assert.AreEqual(d.date_edited.HasValue, false);
629		}
630
631		[Test]
632		public void NamedArgs()
633		{
634			long first=InsertRecords(10);
635
636			var items=db.Fetch<deco>("WHERE id >= @min_id AND id <= @max_id", 
637						new 
638						{ 
639							min_id = first + 3, 
640							max_id = first + 6 
641						}
642					);
643			Assert.AreEqual(items.Count, 4);
644		}
645
646		[Test]
647		public void SingleOrDefault_Empty()
648		{
649			Assert.IsNull(db.SingleOrDefault<deco>("WHERE id=@0", 0));
650		}
651
652		[Test]
653		public void SingleOrDefault_Single()
654		{
655			var id = InsertRecords(1);
656			Assert.IsNotNull(db.SingleOrDefault<deco>("WHERE id=@0", id));
657		}
658
659		[Test]
660		public void SingleOrDefault_Multiple()
661		{
662			Assert.Throws<InvalidOperationException>(() =>
663			{
664
665				var id = InsertRecords(2);
666				db.SingleOrDefault<deco>("WHERE id>=@0", id);
667			});
668		}
669
670		[Test]
671		public void FirstOrDefault_Empty()
672		{
673			Assert.IsNull(db.FirstOrDefault<deco>("WHERE id=@0", 0));
674		}
675
676		[Test]
677		public void FirstOrDefault_First()
678		{
679			var id = InsertRecords(1);
680			Assert.IsNotNull(db.FirstOrDefault<deco>("WHERE id=@0", id));
681		}
682
683		[Test]
684		public void FirstOrDefault_Multiple()
685		{
686			var id = InsertRecords(2);
687			Assert.IsNotNull(db.FirstOrDefault<deco>("WHERE id>=@0", id));
688		}
689
690		[Test]
691		public void Single_Empty()
692		{
693			Assert.Throws<InvalidOperationException>(() =>
694			{
695				db.Single<deco>("WHERE id=@0", 0);
696			});
697		}
698
699		[Test]
700		public void Single_Single()
701		{
702			var id = InsertRecords(1);
703			Assert.IsNotNull(db.Single<deco>("WHERE id=@0", id));
704		}
705
706		[Test]
707		public void Single_Multiple()
708		{
709			Assert.Throws<InvalidOperationException>(() =>
710			{
711				var id = InsertRecords(2);
712				db.Single<deco>("WHERE id>=@0", id);
713			});
714		}
715
716		[Test]
717		public void First_Empty()
718		{
719			Assert.Throws<InvalidOperationException>(() =>
720			{
721				db.First<deco>("WHERE id=@0", 0);
722			});
723		}
724
725		[Test]
726		public void First_First()
727		{
728			var id = InsertRecords(1);
729			Assert.IsNotNull(db.First<deco>("WHERE id=@0", id));
730		}
731
732		[Test]
733		public void First_Multiple()
734		{
735			var id = InsertRecords(2);
736			Assert.IsNotNull(db.First<deco>("WHERE id>=@0", id));
737		}
738
739		[Test]
740		public void SingleOrDefault_PK_Empty()
741		{
742			Assert.IsNull(db.SingleOrDefault<deco>(0));
743		}
744
745		[Test]
746		public void SingleOrDefault_PK_Single()
747		{
748			var id = InsertRecords(1);
749			Assert.IsNotNull(db.SingleOrDefault<deco>(id));
750		}
751
752		[Test]
753		public void Single_PK_Empty()
754		{
755			Assert.Throws<InvalidOperationException>(() =>
756			{
757				db.Single<deco>(0);
758			});
759		}
760
761		[Test]
762		public void Single_PK_Single()
763		{
764			var id = InsertRecords(1);
765			Assert.IsNotNull(db.Single<deco>(id));
766		}
767
768		[Test]
769		public void AutoSelect_SelectPresent()
770		{
771			var id = InsertRecords(1);
772			var a = db.SingleOrDefault<deco>("SELECT * FROM petapoco WHERE id=@0", id);
773			Assert.IsNotNull(a);
774			Assert.AreEqual(a.id, id);
775		}
776
777		[Test]
778		public void AutoSelect_SelectMissingFromMissing()
779		{
780			var id = InsertRecords(1);
781			var a = db.SingleOrDefault<deco>("WHERE id=@0", id);
782			Assert.IsNotNull(a);
783			Assert.AreEqual(a.id, id);
784		}
785
786		[Test]
787		public void AutoSelect_SelectMissingFromPresent()
788		{
789			var id = InsertRecords(1);
790			var a = db.SingleOrDefault<deco>("FROM petapoco WHERE id=@0", id);
791			Assert.IsNotNull(a);
792			Assert.AreEqual(a.id, id);
793		}
794
795		void AssertDynamic(dynamic a, dynamic b)
796		{
797			Assert.AreEqual(a.id, b.id);
798			Assert.AreEqual(a.title, b.title);
799			Assert.AreEqual(a.draft, b.draft);
800			Assert.AreEqual(a.content, b.content);
801			Assert.AreEqual(a.date_created, b.date_created);
802			Assert.AreEqual(a.state, b.state);
803		}
804
805		dynamic CreateExpando()
806		{
807			// Need a rounded date as DB can't store millis
808			var now = DateTime.UtcNow;
809			now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second);
810
811			// Setup a record
812			dynamic o = new System.Dynamic.ExpandoObject();
813			o.title = string.Format("insert {0}", r.Next());
814			o.draft = true;
815			o.content = string.Format("insert {0}", r.Next());
816			o.date_created = now;
817			o.date_edited = now;
818			o.state = (int)State.Maybe;
819
820			return o;
821		}
822		[Test]
823		public void Dynamic_Query()
824		{
825			// Create a random record
826			var o = CreateExpando();
827
828			Assert.IsTrue(db.IsNew("id", o));
829
830			// Insert it
831			db.Insert("petapoco", "id", o);
832			Assert.AreNotEqual(o.id, 0);
833
834			Assert.IsFalse(db.IsNew("id", o));
835
836			// Retrieve it
837			var o2 = db.Single<dynamic>("SELECT * FROM petapoco WHERE id=@0", o.id);
838
839			Assert.IsFalse(db.IsNew("id", o2));
840
841			// Check it
842			AssertDynamic(o, o2);
843
844			// Update it
845			o2.title = "New Title";
846			db.Save("petapoco", "id", o2);
847
848			// Retrieve itagain
849			var o3 = db.Single<dynamic>("SELECT * FROM petapoco WHERE id=@0", o.id);
850
851			// Check it
852			AssertDynamic(o2, o3);
853
854			// Delete it
855			db.Delete("petapoco", "id", o3);
856
857			// Should be gone!
858			var o4 = db.SingleOrDefault<dynamic>("SELECT * FROM petapoco WHERE id=@0", o.id);
859			Assert.IsNull(o4);
860		}
861	
862		[Test]
863		public void Manual_PrimaryKey()
864		{
865			var o=new petapoco2();
866			o.email="blah@blah.com";
867			o.name="Mr Blah";
868			db.Insert(o);
869
870			var o2 = db.SingleOrDefault<petapoco2>("WHERE email=@0", "blah@blah.com");
871			Assert.AreEqual(o2.name, "Mr Blah");
872		}
873
874		[Test]
875		public void SingleValueRequest()
876		{
877			var id = InsertRecords(1);
878			var id2 = db.SingleOrDefault<long>("SELECT id from petapoco WHERE id=@0", id);
879			Assert.AreEqual(id, id2);
880		}
881	}
882
883}