瀏覽代碼

added sql error check (ability to move business in db); tests

tags/v0.3.0
Robin Thoni 7 年之前
父節點
當前提交
c5a2039706

+ 12
- 12
Luticate2.Utils/DataAccess/LuEfCrudDataAccess.cs 查看文件

@@ -114,9 +114,9 @@ namespace Luticate2.Utils.DataAccess
114 114
 
115 115
 
116 116
 
117
-        protected virtual LuResult<T> _Add<T>(TDboCreate obj, TDbContext db, DbSet<TModel> table)
117
+        protected virtual LuResult<TModel> _Add(TDboCreate dbo, TDbContext db, DbSet<TModel> table)
118 118
         {
119
-            return LuResult<T>.Ok(default(T));
119
+            return LuResult<TModel>.Ok(GetModelFromTCreate(dbo));
120 120
         }
121 121
 
122 122
         public virtual LuResult<T> Add<T>(IEnumerable<TDboCreate> objs, Func<IEnumerable<TDboRead>, T> returnFunc)
@@ -127,14 +127,14 @@ namespace Luticate2.Utils.DataAccess
127 127
                 var transact = BeginTransaction(db);
128 128
                 foreach (var dbo in objs)
129 129
                 {
130
-                    var model = GetModelFromTCreate(dbo);
131
-                    table.Add(model);
132
-                    models.Add(model);
133
-                    var res = _Add<T>(dbo, db, table);
130
+                    var res = _Add(dbo, db, table);
134 131
                     if (!res)
135 132
                     {
136
-                        return res;
133
+                        RollbackTransaction(transact);
134
+                        return res.To<T>();
137 135
                     }
136
+                    table.Add(res.Data);
137
+                    models.Add(res.Data);
138 138
                 }
139 139
                 db.SaveChanges();
140 140
                 foreach (var model in models)
@@ -376,9 +376,10 @@ namespace Luticate2.Utils.DataAccess
376 376
 //            return EditSingleById(id, update, read => read);
377 377
 //        }
378 378
 
379
-        protected virtual LuResult<T> _EditSingleById<T>(TId id, TModel model, TDboUpdate obj, TDbContext db, DbSet<TModel> table)
379
+        protected virtual LuResult<bool> _EditSingleById(TId id, TModel model, TDboUpdate update, TDbContext db, DbSet<TModel> table)
380 380
         {
381
-            return LuResult<T>.Ok(default(T));
381
+            EditModelFromTUpdate(update, model);
382
+            return LuResult<bool>.Ok(true);
382 383
         }
383 384
 
384 385
         public virtual LuResult<T> EditSingleById<T>(TId id, TDboUpdate update, Func<TDboRead, T> returnFunc)
@@ -392,12 +393,11 @@ namespace Luticate2.Utils.DataAccess
392 393
             var editRes = Execute((db, table) =>
393 394
             {
394 395
                 var model = GetEditQueryable(db, table).FirstOrDefault(GetExpression(new KeyValuePair<string, object>("id", guid)));
395
-                EditModelFromTUpdate(update, model);
396
-                var res = _EditSingleById<T>(id, model, update, db, table);
396
+                var res = _EditSingleById(id, model, update, db, table);
397 397
                 if (!res)
398 398
                 {
399 399
                     RollbackTransaction(transact);
400
-                    return res;
400
+                    return res.To<T>();
401 401
                 }
402 402
                 db.Entry(model).State = EntityState.Modified;
403 403
                 db.SaveChanges();

+ 10
- 0
Luticate2.Utils/DataAccess/LuEfDataAccess.cs 查看文件

@@ -23,6 +23,11 @@ namespace Luticate2.Utils.DataAccess
23 23
 
24 24
         protected abstract DbSet<TModel> GetTable(TDbContext db);
25 25
 
26
+        protected virtual LuResult<T> HandleError<T>(Exception e)
27
+        {
28
+            return null;
29
+        }
30
+
26 31
         public virtual LuResult<T> Execute<T>(Func<TDbContext, DbSet<TModel>, LuResult<T>> func)
27 32
         {
28 33
             try
@@ -39,6 +44,11 @@ namespace Luticate2.Utils.DataAccess
39 44
             }
40 45
             catch (Exception e)
41 46
             {
47
+                var err = HandleError<T>(e);
48
+                if (null != err)
49
+                {
50
+                    return err;
51
+                }
42 52
                 return LuResult<T>.Error(LuStatus.DbError, e);
43 53
             }
44 54
         }

+ 37
- 2
Luticate2.Utils/Utils/LuCoreUtilsExtensions.cs 查看文件

@@ -6,6 +6,11 @@ namespace Luticate2.Utils.Utils
6 6
 {
7 7
     public static class LuCoreUtilsExtensions
8 8
     {
9
+        public static bool HasProperty(this Type type, string name)
10
+        {
11
+            return type.GetProperty(name) != null;
12
+        }
13
+
9 14
         public static string ToSnakeCase(this string str)
10 15
         {
11 16
             if (str == null)
@@ -15,14 +20,44 @@ namespace Luticate2.Utils.Utils
15 20
             return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower();
16 21
         }
17 22
 
23
+        public static T ToEnum<T>(this string model)
24
+        {
25
+            return (T) Enum.Parse(typeof(T), model);
26
+        }
27
+
18 28
         public static Guid? ToGuid(this string str)
19 29
         {
20 30
             return str == null ? (Guid?)null : new Guid(str);
21 31
         }
22 32
 
23
-        public static bool HasProperty(this Type type, string name)
33
+        public static string ToDbo(this Guid model)
24 34
         {
25
-            return type.GetProperty(name) != null;
35
+            return model.ToString();
36
+        }
37
+
38
+        public static string ToDbo(this Guid? model)
39
+        {
40
+            return model?.ToDbo();
41
+        }
42
+
43
+        public static DateTime ToDbo(this DateTime model)
44
+        {
45
+            return model.ToLocalTime().ToUniversalTime();
46
+        }
47
+
48
+        public static DateTime? ToDbo(this DateTime? model)
49
+        {
50
+            return model?.ToDbo();
51
+        }
52
+
53
+        public static DateTime ToModel(this DateTime model)
54
+        {
55
+            return model.ToUniversalTime();
56
+        }
57
+
58
+        public static DateTime? ToModel(this DateTime? model)
59
+        {
60
+            return model?.ToModel();
26 61
         }
27 62
     }
28 63
 }

+ 3
- 8
TestUtils/DataAccess/LuUtilsFkPkGuidDataAccess.cs 查看文件

@@ -1,6 +1,7 @@
1 1
 using System;
2 2
 using System.Linq;
3 3
 using Luticate2.Utils.DataAccess;
4
+using Luticate2.Utils.Utils;
4 5
 using Microsoft.EntityFrameworkCore;
5 6
 using TestUtils.DataAccess.Models;
6 7
 using TestUtils.Dbo.FkPkGuid;
@@ -31,18 +32,12 @@ namespace TestUtils.DataAccess
31 32
         protected override void EditModelFromTUpdate(FkPkGuidAddDbo obj, fk_pk_guids model)
32 33
         {
33 34
             model.name = obj.Name;
34
-            model.pk_guid_id = obj.PkGuidId == null ? (Guid?) null : new Guid(obj.PkGuidId);
35
+            model.pk_guid_id = obj.PkGuidId.ToGuid();
35 36
         }
36 37
 
37 38
         protected override FkPkGuidDbo GetDboFromModel(fk_pk_guids model)
38 39
         {
39
-            return new FkPkGuidDbo
40
-            {
41
-                Id = model.id.ToString(),
42
-                Name = model.name,
43
-                PkGuid = model.fk_pk_guid == null ? null : LuUtilsPkGuidDataAccess.GetDboFromModelStatic(model.fk_pk_guid),
44
-                PkGuidId = model.pk_guid_id?.ToString()
45
-            };
40
+            return model.ToDbo();
46 41
         }
47 42
     }
48 43
 }

+ 1
- 7
TestUtils/DataAccess/LuUtilsPkBigSerialDataAccess.cs 查看文件

@@ -32,13 +32,7 @@ namespace TestUtils.DataAccess
32 32
 
33 33
         protected override PkBigSerialDbo GetDboFromModel(pk_bigserial model)
34 34
         {
35
-            return new PkBigSerialDbo
36
-            {
37
-                CreatedAt = model.created_at,
38
-                Id = model.id,
39
-                SomeInt = model.some_int,
40
-                SomeText = model.some_text
41
-            };
35
+            return model.ToDbo();
42 36
         }
43 37
 
44 38
         protected override Expression<Func<pk_bigserial, bool>> GetFilterExpression(LuFilterDbo filter)

+ 33
- 53
TestUtils/DataAccess/LuUtilsPkGuidDataAccess.cs 查看文件

@@ -1,11 +1,10 @@
1 1
 using System;
2
-using System.Collections.Generic;
3
-using System.Linq;
4 2
 using System.Linq.Expressions;
5 3
 using Luticate2.Utils.DataAccess;
6 4
 using Luticate2.Utils.Dbo.Filter;
7 5
 using Luticate2.Utils.Dbo.Result;
8 6
 using Microsoft.EntityFrameworkCore;
7
+using Npgsql;
9 8
 using TestUtils.DataAccess.Models;
10 9
 using TestUtils.Dbo.PkGuid;
11 10
 
@@ -27,27 +26,39 @@ namespace TestUtils.DataAccess
27 26
             return GetModelFromTUpdate(obj, new pk_guid());
28 27
         }
29 28
 
30
-        protected override void EditModelFromTUpdate(PkGuidAddDbo obj, pk_guid model)
29
+        protected override LuResult<T> HandleError<T>(Exception e)
31 30
         {
32
-            model.some_int = obj.SomeInt;
33
-            model.some_text = obj.SomeText;
31
+            if (e is DbUpdateException)
32
+            {
33
+                var pge = e.InnerException as PostgresException;
34
+                if (pge != null)
35
+                {
36
+                    if (pge.ConstraintName == "pk_guid_some_text_key")
37
+                    {
38
+                        return LuResult<T>.Error(LuStatus.InputError, e, "someText already exists");
39
+                    }
40
+                    if (pge.ConstraintName == "pkguid_some_text_check_insert")
41
+                    {
42
+                        return LuResult<T>.Error(LuStatus.InputError, e, "someText can not end with '_edited'");
43
+                    }
44
+                    if (pge.ConstraintName == "pkguid_some_text_check_update")
45
+                    {
46
+                        return LuResult<T>.Error(LuStatus.InputError, e, "someText must end with '_edited'");
47
+                    }
48
+                }
49
+            }
50
+            return null;
34 51
         }
35 52
 
36
-        public static PkGuidDbo GetDboFromModelStatic(pk_guid model)
53
+        protected override void EditModelFromTUpdate(PkGuidAddDbo obj, pk_guid model)
37 54
         {
38
-            return new PkGuidDbo
39
-            {
40
-                CreatedAt = model.created_at,
41
-                UpdatedAt = model.updated_at,
42
-                Id = model.id.ToString(),
43
-                SomeInt = model.some_int,
44
-                SomeText = model.some_text
45
-            };
55
+            model.some_int = obj.SomeInt;
56
+            model.some_text = obj.SomeText;
46 57
         }
47 58
 
48 59
         protected override PkGuidDbo GetDboFromModel(pk_guid model)
49 60
         {
50
-            return GetDboFromModelStatic(model);
61
+            return model.ToDbo();
51 62
         }
52 63
 
53 64
         protected override Expression<Func<pk_guid, bool>> GetFilterExpression(LuFilterDbo filter)
@@ -55,48 +66,17 @@ namespace TestUtils.DataAccess
55 66
             return model => LuUtilsDbContext.lu_texts_match(filter.Query, model.some_text + " " + model.some_int.ToString());
56 67
         }
57 68
 
58
-        public LuResult<bool> SomeTextExists(string someText)
59
-        {
60
-            return Execute((db, table) => LuResult<bool>.Ok(table.Any(guid => guid.some_text == someText)));
61
-        }
62
-
63
-        public override LuResult<T> Add<T>(IEnumerable<PkGuidAddDbo> objs, Func<IEnumerable<PkGuidDbo>, T> returnFunc)
69
+        protected override LuResult<pk_guid> _Add(PkGuidAddDbo dbo, LuUtilsDbContext db, DbSet<pk_guid> table)
64 70
         {
65
-            IList<pk_guid> models = new List<pk_guid>();
66
-            var addRes = Execute((db, table) =>
71
+            if (dbo.SomeInt == 2424)
67 72
             {
68
-                var transact = BeginTransaction(db);
69
-                foreach (var dbo in objs)
70
-                {
71
-                    var quoteRequest = GetModelFromTCreate(dbo);
72
-                    models.Add(quoteRequest);
73
-                    table.Add(quoteRequest);
74
-                }
75
-                db.SaveChanges();
76
-                foreach (var model in models)
77
-                {
78
-                    db.Entry(model).State = EntityState.Detached;
79
-                }
80
-                foreach (var pkGuid in models)
81
-                {
82
-                    if (pkGuid.some_int == 2424)
83
-                    {
84
-                        throw new Exception("Test unexpected db error");
85
-                    }
86
-                    if (pkGuid.some_int == 4242)
87
-                    {
88
-                        RollbackTransaction(transact);
89
-                        return LuResult<T>.Error(LuStatus.DbError, "Some expected error", "");
90
-                    }
91
-                }
92
-                CommitTransaction(transact);
93
-                return LuResult<T>.Ok(default(T));
94
-            });
95
-            if (!addRes)
73
+                throw new Exception("Test unexpected db error");
74
+            }
75
+            if (dbo.SomeInt == 4242)
96 76
             {
97
-                return addRes;
77
+                return LuResult<pk_guid>.Error(LuStatus.DbError, "Some expected error", "");
98 78
             }
99
-            return GetMultiple(models, returnFunc);
79
+            return LuResult<pk_guid>.Ok(GetModelFromTCreate(dbo));
100 80
         }
101 81
     }
102 82
 }

+ 57
- 0
TestUtils/DataAccess/ModelsToDbo.cs 查看文件

@@ -0,0 +1,57 @@
1
+using Luticate2.Utils.Utils;
2
+using TestUtils.DataAccess.Models;
3
+using TestUtils.Dbo.FkPkGuid;
4
+using TestUtils.Dbo.PkBigSerial;
5
+using TestUtils.Dbo.PkGuid;
6
+
7
+namespace TestUtils.DataAccess
8
+{
9
+    public static class ModelsToDbo
10
+    {
11
+        public static PkGuidDbo ToDbo(this pk_guid model)
12
+        {
13
+            if (model == null)
14
+            {
15
+                return null;
16
+            }
17
+            return new PkGuidDbo
18
+            {
19
+                CreatedAt = model.created_at,
20
+                UpdatedAt = model.updated_at,
21
+                Id = model.id.ToString(),
22
+                SomeInt = model.some_int,
23
+                SomeText = model.some_text
24
+            };
25
+        }
26
+
27
+        public static FkPkGuidDbo ToDbo(this fk_pk_guids model)
28
+        {
29
+            if (model == null)
30
+            {
31
+                return null;
32
+            }
33
+            return new FkPkGuidDbo
34
+            {
35
+                Id = model.id.ToString(),
36
+                Name = model.name,
37
+                PkGuid = model.fk_pk_guid.ToDbo(),
38
+                PkGuidId = model.pk_guid_id.ToDbo()
39
+            };
40
+        }
41
+
42
+        public static PkBigSerialDbo ToDbo(this pk_bigserial model)
43
+        {
44
+            if (model == null)
45
+            {
46
+                return null;
47
+            }
48
+            return new PkBigSerialDbo
49
+            {
50
+                CreatedAt = model.created_at,
51
+                Id = model.id,
52
+                SomeInt = model.some_int,
53
+                SomeText = model.some_text
54
+            };
55
+        }
56
+    }
57
+}

+ 8
- 5
TestUtils/EfCrudDataAccess/LuEfUpdateDataAccessTest.cs 查看文件

@@ -702,11 +702,12 @@ namespace TestUtils.EfCrudDataAccess
702 702
                 var ids = res.Data.ToList();
703 703
 
704 704
                 dbos[0].SomeInt = -1;
705
+                dbos[0].SomeText += "_edited";
705 706
 
706 707
                 var edit = service.EditSingleById(ids[0], dbos[0], d => d);
707 708
                 Assert.Equal(LuStatus.Success, edit.Status);
708 709
                 Assert.Equal(-1, edit.Data.SomeInt);
709
-                Assert.Equal("442", edit.Data.SomeText);
710
+                Assert.Equal("442_edited", edit.Data.SomeText);
710 711
 
711 712
                 var get = service.GetMultiple(guid => guid.some_text);
712 713
                 Assert.Equal(LuStatus.Success, get.Status);
@@ -723,7 +724,7 @@ namespace TestUtils.EfCrudDataAccess
723 724
 
724 725
                 dbo = get.Data.Data[2];
725 726
                 Assert.Equal(-1, dbo.SomeInt);
726
-                Assert.Equal("442", dbo.SomeText);
727
+                Assert.Equal("442_edited", dbo.SomeText);
727 728
             });
728 729
         }
729 730
 
@@ -755,6 +756,7 @@ namespace TestUtils.EfCrudDataAccess
755 756
                 var ids = res.Data.ToList();
756 757
 
757 758
                 dbos[0].SomeInt = -1;
759
+                dbos[0].SomeText += "_edited";
758 760
 
759 761
                 var edit = service.EditSingleByIdId(ids[0], dbos[0]);
760 762
                 Assert.Equal(LuStatus.Success, edit.Status);
@@ -774,7 +776,7 @@ namespace TestUtils.EfCrudDataAccess
774 776
 
775 777
                 dbo = get.Data.Data[2];
776 778
                 Assert.Equal(-1, dbo.SomeInt);
777
-                Assert.Equal("442", dbo.SomeText);
779
+                Assert.Equal("442_edited", dbo.SomeText);
778 780
             });
779 781
         }
780 782
 
@@ -806,11 +808,12 @@ namespace TestUtils.EfCrudDataAccess
806 808
                 var ids = res.Data.ToList();
807 809
 
808 810
                 dbos[0].SomeInt = -1;
811
+                dbos[0].SomeText += "_edited";
809 812
 
810 813
                 var edit = service.EditSingleByIdDbo(ids[0], dbos[0]);
811 814
                 Assert.Equal(LuStatus.Success, edit.Status);
812 815
                 Assert.Equal(-1, edit.Data.SomeInt);
813
-                Assert.Equal("442", edit.Data.SomeText);
816
+                Assert.Equal("442_edited", edit.Data.SomeText);
814 817
 
815 818
                 var get = service.GetMultiple(guid => guid.some_text);
816 819
                 Assert.Equal(LuStatus.Success, get.Status);
@@ -827,7 +830,7 @@ namespace TestUtils.EfCrudDataAccess
827 830
 
828 831
                 dbo = get.Data.Data[2];
829 832
                 Assert.Equal(-1, dbo.SomeInt);
830
-                Assert.Equal("442", dbo.SomeText);
833
+                Assert.Equal("442_edited", dbo.SomeText);
831 834
             });
832 835
         }
833 836
     }

+ 0
- 48
WebApiUtils/Business/PkGuidBusiness.cs 查看文件

@@ -1,5 +1,4 @@
1 1
 using Luticate2.Utils.Business;
2
-using Luticate2.Utils.Dbo.Result;
3 2
 using TestUtils.DataAccess;
4 3
 using TestUtils.Dbo.PkGuid;
5 4
 
@@ -7,56 +6,9 @@ namespace WebApiUtils.Business
7 6
 {
8 7
     public class PkGuidBusiness : LuCrudBusiness<LuUtilsPkGuidDataAccess, PkGuidAddDbo, PkGuidDbo, PkGuidAddDbo, string>
9 8
     {
10
-        private readonly LuUtilsPkGuidDataAccess _dataAccess;
11
-
12 9
         public PkGuidBusiness(LuUtilsPkGuidDataAccess dataAccess, LuNotificationsBusiness notificationsBusiness) : base(dataAccess, notificationsBusiness)
13 10
         {
14
-            _dataAccess = dataAccess;
15 11
             EntityType = "pkguid";
16 12
         }
17
-
18
-        public LuResult<bool> SomeTextExists(string someText)
19
-        {
20
-            return _dataAccess.SomeTextExists(someText);
21
-        }
22
-
23
-        protected override LuResult<PkGuidAddDbo> CheckAdd(PkGuidAddDbo obj)
24
-        {
25
-            var res = SomeTextExists(obj.SomeText);
26
-            if (!res)
27
-            {
28
-                return res.To<PkGuidAddDbo>();
29
-            }
30
-            if (res.Data)
31
-            {
32
-                return LuResult<PkGuidAddDbo>.Error(LuStatus.InputError, "someText already exists", "");
33
-            }
34
-            if (obj.SomeText.EndsWith("_edited"))
35
-            {
36
-                return LuResult<PkGuidAddDbo>.Error(LuStatus.InputError, "someText can not end with '_edited'", "");
37
-            }
38
-            return LuResult<PkGuidAddDbo>.Ok(obj);
39
-        }
40
-
41
-        protected override LuResult<PkGuidAddDbo> CheckEdit(PkGuidDbo dbo, PkGuidAddDbo update)
42
-        {
43
-            if (dbo.SomeText != update.SomeText)
44
-            {
45
-                var res = SomeTextExists(update.SomeText);
46
-                if (!res)
47
-                {
48
-                    return res.To<PkGuidAddDbo>();
49
-                }
50
-                if (res.Data)
51
-                {
52
-                    return LuResult<PkGuidAddDbo>.Error(LuStatus.InputError, "someText already exists", "");
53
-                }
54
-            }
55
-            if (!update.SomeText.EndsWith("_edited"))
56
-            {
57
-                return LuResult<PkGuidAddDbo>.Error(LuStatus.InputError, "someText must end with '_edited'", "");
58
-            }
59
-            return LuResult<PkGuidAddDbo>.Ok(update);
60
-        }
61 13
     }
62 14
 }

Loading…
取消
儲存