├── .gitattributes ├── .gitignore ├── CSJsonDB.csproj ├── LICENSE ├── README.md ├── helpers └── ExtensionMethods.cs └── src └── JsonDB.cs /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Make sh files under the build directory always have LF as line endings 8 | ############################################################################### 9 | *.sh eol=lf 10 | 11 | ############################################################################### 12 | # Set default behavior for command prompt diff. 13 | # 14 | # This is need for earlier builds of msysgit that does not have it on by 15 | # default for csharp files. 16 | # Note: This is only used by command line 17 | ############################################################################### 18 | #*.cs diff=csharp 19 | 20 | ############################################################################### 21 | # Set the merge driver for project and solution files 22 | # 23 | # Merging from the command prompt will add diff markers to the files if there 24 | # are conflicts (Merging from VS is not affected by the settings below, in VS 25 | # the diff markers are never inserted). Diff markers may cause the following 26 | # file extensions to fail to load in VS. An alternative would be to treat 27 | # these files as binary and thus will always conflict and require user 28 | # intervention with every merge. To do so, just uncomment the entries below 29 | ############################################################################### 30 | #*.sln merge=binary 31 | #*.csproj merge=binary 32 | #*.vbproj merge=binary 33 | #*.vcxproj merge=binary 34 | #*.vcproj merge=binary 35 | #*.dbproj merge=binary 36 | #*.fsproj merge=binary 37 | #*.lsproj merge=binary 38 | #*.wixproj merge=binary 39 | #*.modelproj merge=binary 40 | #*.sqlproj merge=binary 41 | #*.wwaproj merge=binary 42 | 43 | ############################################################################### 44 | # behavior for image files 45 | # 46 | # image files are treated as binary by default. 47 | ############################################################################### 48 | #*.jpg binary 49 | #*.png binary 50 | #*.gif binary 51 | 52 | ############################################################################### 53 | # diff behavior for common document formats 54 | # 55 | # Convert binary document formats to text before diffing them. This feature 56 | # is only available from the command line. Turn it on by uncommenting the 57 | # entries below. 58 | ############################################################################### 59 | #*.doc diff=astextplain 60 | #*.DOC diff=astextplain 61 | #*.docx diff=astextplain 62 | #*.DOCX diff=astextplain 63 | #*.dot diff=astextplain 64 | #*.DOT diff=astextplain 65 | #*.pdf diff=astextplain 66 | #*.PDF diff=astextplain 67 | #*.rtf diff=astextplain 68 | #*.RTF diff=astextplain 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Folders 2 | artifacts/ 3 | bin/ 4 | obj/ 5 | .dotnet/ 6 | .nuget/ 7 | .packages/ 8 | .tools/ 9 | .vs/ 10 | .vscode/ 11 | node_modules/ 12 | BenchmarkDotNet.Artifacts/ 13 | .gradle/ 14 | src/SignalR/clients/**/dist/ 15 | modules/ 16 | 17 | # File extensions 18 | *.aps 19 | *.binlog 20 | *.dll 21 | *.DS_Store 22 | *.exe 23 | *.idb 24 | *.lib 25 | *.log 26 | *.pch 27 | *.pdb 28 | *.pidb 29 | *.psess 30 | *.res 31 | *.snk 32 | *.suo 33 | *.tlog 34 | *.user 35 | *.userprefs 36 | *.vspx 37 | 38 | # Specific files, typically generated by tools 39 | launchSettings.json 40 | msbuild.ProjectImports.zip 41 | StyleCop.Cache 42 | UpgradeLog.htm 43 | 44 | # DocFX site generation (for now) 45 | _site/ -------------------------------------------------------------------------------- /CSJsonDB.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net5.0 5 | CSJsonDB 6 | 1.1.0 7 | https://github.com/Khelechy/CSJsonDB.git 8 | MIT 9 | git 10 | Kelechi Onyekwere 11 | khelechy 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Onyekwere Kelechi Mark 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CSJsonDB 2 | ## Introduction 3 | 4 | This is a simple C# package that performs basic CRUD ( Create, Read, Update, Delete ) operations on a Json file, used for sample minimalistic DBs. 5 | 6 | ## Installation 7 | 8 | Install via .NET CLI 9 | 10 | ```bash 11 | dotnet add package CSJsonDB --version 1.1.0 12 | ``` 13 | Install via Package Manager 14 | 15 | ```bash 16 | Install-Package CSJsonDB --version 1.1.0 17 | ``` 18 | 19 | ### Add the namespace directive `using CSJsonDB;` `IMPORTANT` 20 | 21 | Sample DB `users.db` 22 | 23 | ```json 24 | { 25 | "users": [ 26 | { 27 | "id": 1, 28 | "firstname": "kelechi", 29 | "lastname": "onyekwere", 30 | "age": 19, 31 | "verified": true 32 | }, 33 | { 34 | "id": 2, 35 | "firstname": "john", 36 | "lastname": "doe", 37 | "age": 33, 38 | "verified": true 39 | }, 40 | { 41 | "id": 3, 42 | "firstname": "mark", 43 | "lastname": "parker", 44 | "age": 20, 45 | "verified": false 46 | } 47 | ] 48 | } 49 | ``` 50 | 51 | ### Load the Sample DB `IMPORTANT` 52 | 53 | ```c# 54 | var db = JsonDB.Load("filepathtosampledb/users.db"); 55 | ``` 56 | 57 | ## Available Methods 🧨 58 | 59 | >**NOTE**
60 | >Responses are returned as objects. You can use `.ToJsonString()` method to return json string from a json object 61 | 62 | ### Load 63 | 64 | ```c# 65 | var db = JsonDB.Load(string filePath); 66 | ``` 67 | 68 | 69 | ### ToJsonString 70 | 71 | ```c# 72 | db.Select("users").Where("id", 2).ToJsonString(); 73 | ``` 74 | result: `string` Returns the json string of the object. 75 | 76 | ### Select 77 | 78 | ```c# 79 | db.Select(string table); 80 | ``` 81 | 82 | #### Sample 83 | ```c# 84 | db.Select("users"); 85 | ``` 86 | result: `object` 87 | ```json 88 | [ 89 | { 90 | "id": 1, 91 | "firstname": "kelechi", 92 | "lastname": "onyekwere", 93 | "age": 19, 94 | "verified": true 95 | }, 96 | { 97 | "id": 2, 98 | "firstname": "john", 99 | "lastname": "doe", 100 | "age": 33, 101 | "verified": true 102 | }, 103 | { 104 | "id": 3, 105 | "firstname": "mark", 106 | "lastname": "parker", 107 | "age": 20, 108 | "verified": false 109 | } 110 | ] 111 | ``` 112 | 113 | ### Where 114 | ```c# 115 | db.Select(string table).Where(string key, dynamic value); 116 | ``` 117 | #### Sample 118 | ```c# 119 | db.Select("users").Where("id", 2); 120 | ``` 121 | result: `List` 122 | ```json 123 | [ 124 | { 125 | "id": 2, 126 | "firstname": "john", 127 | "lastname": "doe", 128 | "age": 33, 129 | "verified": true 130 | }, 131 | ] 132 | ``` 133 | 134 | ### Add 135 | ```c# 136 | db.Add(string table, object newData); 137 | ``` 138 | #### Sample 139 | ```c# 140 | var newUser = new { 141 | id = 3, 142 | firstname = matt, 143 | lastname = doe, 144 | age = 23, 145 | verified = false 146 | }; 147 | 148 | db.Add("users", newUser); 149 | ``` 150 | result: void 151 | 152 | ### Delete 153 | ```c# 154 | db.Delete(string table, string key, dynamic value); 155 | ``` 156 | #### Sample 157 | ```c# 158 | db.Delete("users", "id", 1); 159 | ``` 160 | result: void 161 | 162 | ### Update 163 | ```c# 164 | db.Update(string table, string key, dynamic value, object newData); 165 | ``` 166 | #### Sample 167 | ```c# 168 | var updateUser = new { 169 | verified = true 170 | }; 171 | 172 | db.Update("users", "id", 3, updateUser); 173 | ``` 174 | result: `object` 175 | ```json 176 | [ 177 | { 178 | "id": 3, 179 | "firstname": "mark", 180 | "lastname": "parker", 181 | "age": 20, 182 | "verified": true 183 | }, 184 | ] 185 | ``` 186 | 187 | 188 | ## Contribution 189 | 190 | If you find an issue with this package or you have any suggestion please help out. I am not perfect. 191 | -------------------------------------------------------------------------------- /helpers/ExtensionMethods.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json.Linq; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace CSJsonDB.helpers 9 | { 10 | public static class ExtensionMethods 11 | { 12 | public static JArray ToDataList(this object data) 13 | { 14 | if (data != null) 15 | { 16 | try 17 | { 18 | var token = JToken.Parse(data.ToString()); 19 | if (token is JArray) 20 | { 21 | 22 | JArray dataArray = (JArray)data; 23 | return dataArray; 24 | } 25 | else 26 | { 27 | throw new Exception("The preloaded data is not a Json Array"); 28 | } 29 | } 30 | catch (Exception ex) 31 | { 32 | throw new Exception(ex.Message.ToString()); 33 | } 34 | } 35 | else 36 | { 37 | throw new Exception("The preloaded data is null"); 38 | } 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/JsonDB.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Linq; 6 | using System.Collections.Generic; 7 | using System.Reflection; 8 | using CSJsonDB.helpers; 9 | 10 | namespace CSJsonDB 11 | { 12 | public static class JsonDB 13 | { 14 | public static string jsonFile; 15 | public static string jsonLocation; 16 | private static JObject _dbObject; 17 | 18 | public static JObject Load(string filePathLoaded) 19 | { 20 | if (!File.Exists(filePathLoaded)) 21 | throw new Exception("File does not exist, please check file or file path"); 22 | try 23 | { 24 | jsonFile = File.ReadAllText(filePathLoaded); 25 | jsonLocation = filePathLoaded; 26 | return _dbObject = JObject.Parse(jsonFile); 27 | } 28 | catch (Exception ex) 29 | { 30 | throw new Exception(ex.Message.ToString()); 31 | } 32 | } 33 | 34 | public static object Select(this object data, string table = "") 35 | { 36 | 37 | if (data != null) 38 | { 39 | try 40 | { 41 | var parsedData = JObject.Parse(data.ToString()); 42 | var result = string.IsNullOrEmpty(table) ? (object)parsedData : (object)parsedData[table]; 43 | return result; 44 | } 45 | catch (Exception ex) 46 | { 47 | throw new Exception(ex.Message.ToString()); 48 | } 49 | } 50 | else 51 | { 52 | throw new Exception("The preloaded data is null"); 53 | } 54 | } 55 | 56 | public static List Where(this object data, string key = "", dynamic value = null) 57 | { 58 | if (data != null) 59 | { 60 | var dataArray = data.ToDataList(); 61 | var newDataArray = new List(); 62 | foreach (var singleData in dataArray.Where(x => x[key] as dynamic == value)) 63 | { 64 | newDataArray.Add(singleData); 65 | } 66 | return newDataArray; 67 | } 68 | else 69 | { 70 | throw new Exception("The preloaded data is null"); 71 | } 72 | 73 | } 74 | 75 | public static void Add(this object data, string table, object newData) 76 | { 77 | if (data != null) 78 | { 79 | try 80 | { 81 | var parsedData = JObject.Parse(data.ToString()); 82 | var result = string.IsNullOrEmpty(table) ? (object)parsedData : (object)parsedData[table]; 83 | var dataArray = result.ToDataList(); 84 | dataArray.Add(JObject.Parse(JsonConvert.SerializeObject(newData, Formatting.Indented))); 85 | parsedData[table] = dataArray; 86 | string newJsonResult = parsedData.ToString(); 87 | File.WriteAllText(jsonLocation, newJsonResult); 88 | } 89 | catch (Exception ex) 90 | { 91 | throw new Exception(ex.Message.ToString()); 92 | } 93 | } 94 | else 95 | { 96 | throw new Exception("The preloaded data is null"); 97 | } 98 | } 99 | 100 | public static void Delete(this object data, string table, string key, dynamic value) 101 | { 102 | if (data != null) 103 | { 104 | try 105 | { 106 | var parsedData = JObject.Parse(data.ToString()); 107 | var result = (object)parsedData[table]; 108 | var dataArray = result.ToDataList(); 109 | var itemToBeDeleted = dataArray.FirstOrDefault(x => x[key] as dynamic == value); 110 | if (itemToBeDeleted == null) 111 | throw new Exception("There are no objects with key: " + key + " , Please check key again"); 112 | dataArray.Remove(itemToBeDeleted); 113 | parsedData[table] = dataArray; 114 | string newJsonResult = parsedData.ToString(); 115 | File.WriteAllText(jsonLocation, newJsonResult); 116 | } 117 | catch (Exception ex) 118 | { 119 | throw new Exception(ex.Message.ToString()); 120 | } 121 | } 122 | else 123 | { 124 | throw new Exception("The preloaded data is null"); 125 | } 126 | } 127 | 128 | public static object Update(this object data, string table, string key, dynamic value, object newData) 129 | { 130 | if (data != null) 131 | { 132 | try 133 | { 134 | var parsedData = JObject.Parse(data.ToString()); 135 | var result = (object)parsedData[table]; 136 | var dataArray = result.ToDataList(); 137 | var x = dataArray.FirstOrDefault(x => x[key] as dynamic == value); 138 | if (x == null) 139 | throw new Exception("There are no objects with key: " + key + " , Please check key again"); 140 | foreach (PropertyInfo prop in newData.GetType().GetProperties()) 141 | { 142 | var valueObject = prop.GetValue(newData, null); 143 | x[prop.Name] = JToken.FromObject(valueObject); 144 | } 145 | parsedData[table] = dataArray; 146 | string newJsonResult = parsedData.ToString(); 147 | File.WriteAllText(jsonLocation, newJsonResult); 148 | return x; 149 | } 150 | catch (Exception ex) 151 | { 152 | throw new Exception(ex.Message.ToString()); 153 | } 154 | } 155 | else 156 | { 157 | throw new Exception("The preloaded data is null"); 158 | } 159 | } 160 | 161 | public static string ToJsonString(this object data) 162 | { 163 | if(data != null) 164 | { 165 | return JsonConvert.SerializeObject(data); 166 | } 167 | else 168 | { 169 | throw new Exception("The preloaded data is null"); 170 | } 171 | } 172 | 173 | /// 174 | /// Gets the next available ID for a specified table and ID field 175 | /// 176 | /// The table name to search 177 | /// The ID field name (default: "id") 178 | /// The next available ID 179 | public static int GetNextId(string table, string idField = "id") 180 | { 181 | if (_dbObject == null) 182 | throw new Exception("Database not loaded. Call Load() first."); 183 | 184 | var tableArray = _dbObject[table] as JArray; 185 | if (tableArray == null) 186 | return 1; // Return 1 if table doesn't exist or is empty 187 | 188 | int maxId = 0; 189 | 190 | foreach (var item in tableArray) 191 | { 192 | if (item[idField] != null && item[idField].Type == JTokenType.Integer) 193 | { 194 | int currentId = item[idField].Value(); 195 | if (currentId > maxId) 196 | maxId = currentId; 197 | } 198 | } 199 | 200 | return maxId + 1; 201 | } 202 | } 203 | } 204 | --------------------------------------------------------------------------------