Browse Source

Added ability to query and drop non-entity tables in database server
Tweaked User Tracking to enable stores to increment usages

frogsoftware 8 months ago
parent
commit
a9eddfb383

+ 6 - 0
InABox.Database/IProvider.cs

@@ -21,6 +21,12 @@ public interface IProvider
     Logger Logger { get; set; }
 
     IEnumerable<object[]> List<T>(Filter<T>? filter = null, Columns<T>? columns = null, SortOrder<T>? sort = null, CoreRange? range = null) where T : Entity, new();
+
+    IEnumerable<object[]> List(string sql);
+    
+    CoreTable? Query<T>(string sql) where T : BaseObject;
+    
+    void DropTable<T>();
     
     CoreTable Query<T>(Filter<T>? filter = null, Columns<T>? columns = null, SortOrder<T>? sort = null, 
         CoreRange? range = null, bool log = false, bool distinct = false) where T : Entity, new();

+ 7 - 1
InABox.Database/Stores/Store.cs

@@ -57,7 +57,8 @@ namespace InABox.Database
 
             return type;
         }
-
+        
+        
         private void UpdateUserTracking(UserTrackingAction action)
         {
             if (IsSubStore)
@@ -73,6 +74,11 @@ namespace InABox.Database
             if (type == null)
                 return;
 
+            UpdateUserTracking(type, action);
+        }
+
+        protected void UpdateUserTracking(Type type, UserTrackingAction action)
+        {
             if (UserTrackingCache.Date != DateTime.Today)
             {
                 var tdata = Provider.Query(

+ 103 - 7
inabox.database.sqlite/SQLiteProvider.cs

@@ -1284,7 +1284,7 @@ public class SQLiteProviderFactory : IProviderFactory
     //         if (!db_views.ContainsValue(type_view))
     //             ExecuteSQL(access, type_view);            
     // }
-
+    
     #endregion
 
     private void Log(LogType type, string message)
@@ -1312,8 +1312,7 @@ public class SQLiteProvider : IProvider
             type = e.Statement.ToUpper().StartsWith(update) ? LogType.Update : type;
         Logger.Send(type, "", e.Statement + ";");
     }
-
-
+    
     internal SQLiteReadAccessor GetReadAccess()
     {
         var result = new SQLiteReadAccessor(Factory.URL);
@@ -1327,6 +1326,28 @@ public class SQLiteProvider : IProvider
         result.Connection.Trace += Connection_Trace;
         return result;
     }
+    
+    public void DropTable<T>()
+    {
+        var _tablename = typeof(T).EntityName().Split('.').Last();
+        using (var _access = GetWriteAccess())
+        {
+            if (!typeof(T).IsSubclassOf(typeof(Entity)))
+            {
+                using (var _command = _access.CreateCommand())
+                {
+                    _command.CommandText = $"select name from sqlite_master where type='table' and name='{_tablename}';";
+                    bool exists = false;
+                    using (var _reader = _command.ExecuteReader())
+                    {
+                        exists = _reader.HasRows;
+                    }
+                    if (exists)
+                        ExecuteSQL(_access, $"DROP TABLE {_tablename}");
+                }
+            }
+        }
+    }
 
     internal int ExecuteSQL(SQLiteWriteAccessor writer, string statement)
     {
@@ -1339,7 +1360,7 @@ public class SQLiteProvider : IProvider
                 result = command.ExecuteNonQuery();
             }
         }
-        catch (Exception)
+        catch (Exception e)
         {
             throw;
         }
@@ -2755,9 +2776,9 @@ public class SQLiteProvider : IProvider
         return result;
     }
 
-    #region Query
-
-    public IEnumerable<object[]> List<T>(Filter<T>? filter = null, Columns<T>? columns = null, SortOrder<T>? sort = null, CoreRange? range = null) where T : Entity, new()
+    #region List
+    
+       public IEnumerable<object[]> List<T>(Filter<T>? filter = null, Columns<T>? columns = null, SortOrder<T>? sort = null, CoreRange? range = null) where T : Entity, new()
     {
         //Dictionary<String, TimeSpan> stopwatch = new Dictionary<string, TimeSpan>();
         //Stopwatch sw = new Stopwatch();
@@ -2796,6 +2817,81 @@ public class SQLiteProvider : IProvider
         return result;
     }
 
+    public IEnumerable<object[]> List(string sql)
+    {
+        var result = new List<object[]>();
+        
+        using (var access = GetReadAccess())
+        {
+            using (var command = access.CreateCommand())
+            {
+                command.CommandText = sql;
+                
+                using (var reader = command.ExecuteReader())
+                {
+                    var _colCount = reader.GetColumnSchema().Count;
+                    
+                    foreach (var row in reader)
+                    {
+                        var values = GetValues(reader, _colCount);
+                        result.Add(values);
+                    }
+                    reader.Close();
+                }
+            }
+        }
+
+        return result;
+    }
+    
+    #endregion
+    
+    #region Query
+
+    public CoreTable? Query<T>(string sql) where T: BaseObject
+    {
+        CoreTable? _result = null;
+        var props = CoreUtils.PropertyInfoList(typeof(T), p => true, true);
+        try
+        {
+            using (var access = GetReadAccess())
+            {
+                using (var command = access.CreateCommand())
+                {
+                    command.CommandText = sql;
+                    using (var reader = command.ExecuteReader())
+                    { 
+                        _result = new CoreTable();
+                        var schema = reader.GetColumnSchema();
+                        foreach (var column in schema)
+                        {
+                            if (props.TryGetValue(column.ColumnName, out var _info))
+                                _result.Columns.Add(new CoreColumn(_info.PropertyType, column.ColumnName));
+                            else
+                                _result.Columns.Add(new CoreColumn(column.DataType, column.ColumnName));
+                        }
+
+                        var _colCount = reader.GetColumnSchema().Count;
+
+                        while (reader.Read())
+                        {
+                            var _row = _result.NewRow();
+                            for (int i=0; i <_colCount; i++)
+                                ReadAndDecodeValue(_result,reader,_row,i);
+                            _result.Rows.Add(_row);
+                        }
+                        reader.Close();
+                    }
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            Logger.Send(LogType.Error,"",$"Exception in Query: {sql}\nMessage: {e.Message}\nStackTrace: {e.StackTrace}");
+        }
+        return _result;
+    }
+    
     private CoreTable DoQueryNonGeneric(Type T, IFilter? filter = null, IColumns? columns = null, ISortOrder? sort = null, CoreRange? range = null, bool log = false, bool distinct = false)
     {
         var start = DateTime.Now;