From 715d6b81ba2675d17aad0b6b0fd3eabf7db84ea1 Mon Sep 17 00:00:00 2001 From: SundaePixel <74124581+SundaePixel@users.noreply.github.com> Date: Sat, 7 Jun 2025 00:20:49 -0500 Subject: [PATCH] Godot 4x MongoDB port --- addons/MongoDB/MongoAPI.cs | 36 +- addons/MongoDB/MongoClient/_MongoClient.cs | 95 ++-- .../MongoCollection/_MongoCollection.cs | 491 ++++++++++++++++-- .../MongoDB/MongoDatabase/_MongoDatabase.cs | 97 ++-- .../MongoDB/MongoDocument/MongoDocument.tscn | 6 +- .../MongoDB/MongoDocument/_MongoDocument.cs | 6 +- addons/MongoDB/Utils/Converters.cs | 158 +++--- addons/MongoDB/mongoDB-icon.png.import | 32 +- addons/MongoDB/mongodb-bridge-icon.png.import | 34 ++ addons/MongoDB/mongodb-bridge.gd | 18 +- 10 files changed, 720 insertions(+), 253 deletions(-) create mode 100644 addons/MongoDB/mongodb-bridge-icon.png.import diff --git a/addons/MongoDB/MongoAPI.cs b/addons/MongoDB/MongoAPI.cs index ccb468c..3452dd5 100644 --- a/addons/MongoDB/MongoAPI.cs +++ b/addons/MongoDB/MongoAPI.cs @@ -4,25 +4,25 @@ using System.Collections.Generic; using MongoDB.Bson; using MongoDB.Driver; -using MongoDB.Driver.Core; -public class MongoAPI : Node +[Tool] +public partial class MongoAPI : Node { - [Export] - private String host = "mongodb://127.0.0.1:27017"; - private String addonPath = "res://addons/MongoDB/"; - public _MongoClient Connect(String hostIp){ - return this.Connect(hostIp, true); - } - public _MongoClient Connect(String hostIp, bool checkSslCertificate) - { - host = hostIp; - var MongoClientScene = (PackedScene) ResourceLoader.Load(addonPath+"MongoClient/MongoClient.tscn"); - var ClientScene = MongoClientScene.Instance() as _MongoClient; - AddChild(ClientScene); - ClientScene.LoadClient(new MongoClient(host), addonPath, checkSslCertificate); - ClientScene.Name = host; - return ClientScene; - } + [Export] + private String host = "mongodb://127.0.0.1:27017"; + private String addonPath = "res://addons/MongoDB/"; + public _MongoClient Connect(String hostIp){ + return this.Connect(hostIp, true); + } + public _MongoClient Connect(String hostIp, bool checkSslCertificate) + { + host = hostIp; + var MongoClientScene = (PackedScene) ResourceLoader.Load(addonPath+"MongoClient/MongoClient.tscn"); + var ClientScene = MongoClientScene.Instantiate() as _MongoClient; + AddChild(ClientScene); + ClientScene.LoadClient(new MongoClient(host), addonPath, checkSslCertificate, host); + ClientScene.Name = host; + return ClientScene; + } } diff --git a/addons/MongoDB/MongoClient/_MongoClient.cs b/addons/MongoDB/MongoClient/_MongoClient.cs index 0eb5c57..cf49b30 100644 --- a/addons/MongoDB/MongoClient/_MongoClient.cs +++ b/addons/MongoDB/MongoClient/_MongoClient.cs @@ -5,62 +5,57 @@ using System.Collections.Generic; using MongoDB.Bson; using MongoDB.Driver; -using MongoDB.Driver.Core; -public class _MongoClient : Node +public partial class _MongoClient : Node { - private String addonPath; - private MongoClient client; + private String addonPath; + private MongoClient client; - public void LoadClient(MongoClient mongoClient, String path, bool checkSslCertificate) - { - client = mongoClient; - addonPath = path; - - if (!checkSslCertificate){ - var settings = client.Settings.Clone(); - settings.SslSettings = new SslSettings() { - CheckCertificateRevocation = true, - ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true - }; - + public void LoadClient(MongoClient mongoClient, String path, bool checkSslCertificate, string connectionString = null) + { + client = mongoClient; + addonPath = path; + + if (!checkSslCertificate && connectionString != null) + { + var settings = MongoClientSettings.FromConnectionString(connectionString); + settings.AllowInsecureTls = true; client = new MongoClient(settings); } - - } - - public Godot.Collections.Array GetDatabaseList() - { - var databaseList = client.ListDatabases().ToList(); - var databaseArray = Converters.ConvertBsonListToJsonList(databaseList); - return databaseArray; - } - - public Godot.Collections.Array GetDatabaseNameList() - { - var databaseNameList = client.ListDatabaseNames().ToList(); - var databaseNameArray = Converters.ConvertStringListToArray(databaseNameList); - return databaseNameArray; - } - - public _MongoDatabase GetDatabase(String databaseName) - { - var database = client.GetDatabase(databaseName); - _MongoDatabase DatabaseScene = null; - if (!HasNode(databaseName)) - { - var MongoDatabaseScene = (PackedScene) ResourceLoader.Load(addonPath+"MongoDatabase/MongoDatabase.tscn"); - DatabaseScene = MongoDatabaseScene.Instance() as _MongoDatabase; - AddChild(DatabaseScene); - DatabaseScene.LoadDatabase(database, addonPath); - DatabaseScene.Name = databaseName; - } - else { - DatabaseScene = (_MongoDatabase)GetNode(databaseName); - } + } + + public Godot.Collections.Array GetDatabaseList() + { + var databaseList = client.ListDatabases().ToList(); + var databaseArray = Converters.ConvertBsonListToJsonList(databaseList); + return databaseArray; + } + + public Godot.Collections.Array GetDatabaseNameList() + { + var databaseNameList = client.ListDatabaseNames().ToList(); + var databaseNameArray = Converters.ConvertStringListToArray(databaseNameList); + return databaseNameArray; + } + + public _MongoDatabase GetDatabase(String databaseName) + { + var database = client.GetDatabase(databaseName); + _MongoDatabase DatabaseScene = null; + if (!HasNode(databaseName)) + { + var MongoDatabaseScene = (PackedScene) ResourceLoader.Load(addonPath+"MongoDatabase/MongoDatabase.tscn"); + DatabaseScene = MongoDatabaseScene.Instantiate() as _MongoDatabase; + AddChild(DatabaseScene); + DatabaseScene.LoadDatabase(database, addonPath); + DatabaseScene.Name = databaseName; + } + else { + DatabaseScene = (_MongoDatabase)GetNode(databaseName); + } - return DatabaseScene; - } + return DatabaseScene; + } } diff --git a/addons/MongoDB/MongoCollection/_MongoCollection.cs b/addons/MongoDB/MongoCollection/_MongoCollection.cs index 2758b4f..f446011 100644 --- a/addons/MongoDB/MongoCollection/_MongoCollection.cs +++ b/addons/MongoDB/MongoCollection/_MongoCollection.cs @@ -5,10 +5,11 @@ using System.Collections.Generic; using MongoDB.Bson; using MongoDB.Driver; -using MongoDB.Driver.Core; using MongoDB.Bson.IO; +using MongoDB.Bson.Serialization; +using System.Text.RegularExpressions; -public class _MongoCollection : Node +public partial class _MongoCollection : Node { private IMongoCollection BsonCollection; private Dictionary JsonCollection; @@ -40,6 +41,346 @@ private void AutoRetrieveDocument() documents = RetrieveDocuments(); } + // Helper method to convert various value types to BsonValue + private BsonValue ConvertToBsonValue(Variant value) + { + switch (value.VariantType) + { + case Variant.Type.String: + return BsonValue.Create(value.AsString()); + case Variant.Type.Int: + return BsonValue.Create(value.AsInt32()); + case Variant.Type.Float: + return BsonValue.Create(value.AsDouble()); + case Variant.Type.Bool: + return BsonValue.Create(value.AsBool()); + case Variant.Type.Array: + var array = value.AsGodotArray(); + var bsonArray = new BsonArray(); + foreach (var item in array) + { + bsonArray.Add(ConvertToBsonValue(item)); + } + return bsonArray; + default: + return BsonValue.Create(value.AsString()); + } + } + + // Enhanced query builder that supports MongoDB operators + private FilterDefinition BuildAdvancedFilter(Dictionary filters) + { + var builder = Builders.Filter; + var filterList = new List>(); + + foreach (var kvp in filters) + { + var fieldName = kvp.Key.ToString(); + var filterValue = kvp.Value; + + FilterDefinition fieldFilter = null; + + // Check if the value is a dictionary (contains operators) + if (filterValue.VariantType == Variant.Type.Dictionary) + { + var operatorDict = filterValue.AsGodotDictionary(); + fieldFilter = BuildOperatorFilter(builder, fieldName, operatorDict); + } + else + { + // Simple equality filter + fieldFilter = builder.Eq(fieldName, ConvertToBsonValue(filterValue)); + } + + if (fieldFilter != null) + { + filterList.Add(fieldFilter); + } + } + + // Handle logical operators at root level + if (filters.ContainsKey("$and")) + { + var andConditions = filters["$and"].AsGodotArray(); + var andFilters = new List>(); + foreach (var condition in andConditions) + { + if (condition.VariantType == Variant.Type.Dictionary) + { + andFilters.Add(BuildAdvancedFilter(condition.AsGodotDictionary())); + } + } + if (andFilters.Count > 0) + { + return builder.And(andFilters); + } + } + + if (filters.ContainsKey("$or")) + { + var orConditions = filters["$or"].AsGodotArray(); + var orFilters = new List>(); + foreach (var condition in orConditions) + { + if (condition.VariantType == Variant.Type.Dictionary) + { + orFilters.Add(BuildAdvancedFilter(condition.AsGodotDictionary())); + } + } + if (orFilters.Count > 0) + { + return builder.Or(orFilters); + } + } + + if (filters.ContainsKey("$nor")) + { + var norConditions = filters["$nor"].AsGodotArray(); + var norFilters = new List>(); + foreach (var condition in norConditions) + { + if (condition.VariantType == Variant.Type.Dictionary) + { + norFilters.Add(BuildAdvancedFilter(condition.AsGodotDictionary())); + } + } + if (norFilters.Count > 0) + { + // Use Not(Or()) instead of Nor() since Nor() doesn't exist + return builder.Not(builder.Or(norFilters)); + } + } + + // Combine all field filters with AND + if (filterList.Count == 0) + { + return builder.Empty; + } + else if (filterList.Count == 1) + { + return filterList[0]; + } + else + { + return builder.And(filterList); + } + } + + // Build filter for a specific field with operators + private FilterDefinition BuildOperatorFilter(FilterDefinitionBuilder builder, string fieldName, Dictionary operatorDict) + { + var filters = new List>(); + + foreach (var op in operatorDict) + { + var operatorName = op.Key.ToString(); + var operatorValue = op.Value; + + FilterDefinition operatorFilter = null; + + switch (operatorName) + { + // Comparison operators + case "$eq": + operatorFilter = builder.Eq(fieldName, ConvertToBsonValue(operatorValue)); + break; + case "$ne": + operatorFilter = builder.Ne(fieldName, ConvertToBsonValue(operatorValue)); + break; + case "$gt": + operatorFilter = builder.Gt(fieldName, ConvertToBsonValue(operatorValue)); + break; + case "$gte": + operatorFilter = builder.Gte(fieldName, ConvertToBsonValue(operatorValue)); + break; + case "$lt": + operatorFilter = builder.Lt(fieldName, ConvertToBsonValue(operatorValue)); + break; + case "$lte": + operatorFilter = builder.Lte(fieldName, ConvertToBsonValue(operatorValue)); + break; + case "$in": + if (operatorValue.VariantType == Variant.Type.Array) + { + var array = operatorValue.AsGodotArray(); + var bsonValues = array.Select(v => ConvertToBsonValue(v)).ToArray(); + operatorFilter = builder.In(fieldName, bsonValues); + } + break; + case "$nin": + if (operatorValue.VariantType == Variant.Type.Array) + { + var array = operatorValue.AsGodotArray(); + var bsonValues = array.Select(v => ConvertToBsonValue(v)).ToArray(); + operatorFilter = builder.Nin(fieldName, bsonValues); + } + break; + + // String operators + case "$regex": + var regexPattern = operatorValue.AsString(); + var regexOptions = RegexOptions.None; + + // Check for options in the same dictionary + if (operatorDict.ContainsKey("$options")) + { + var options = operatorDict["$options"].AsString(); + if (options.Contains("i")) regexOptions |= RegexOptions.IgnoreCase; + if (options.Contains("m")) regexOptions |= RegexOptions.Multiline; + if (options.Contains("s")) regexOptions |= RegexOptions.Singleline; + } + + operatorFilter = builder.Regex(fieldName, new BsonRegularExpression(regexPattern, ConvertRegexOptions(regexOptions))); + break; + + // Array operators + case "$all": + if (operatorValue.VariantType == Variant.Type.Array) + { + var array = operatorValue.AsGodotArray(); + var bsonValues = array.Select(v => ConvertToBsonValue(v)).ToArray(); + operatorFilter = builder.All(fieldName, bsonValues); + } + break; + case "$elemMatch": + if (operatorValue.VariantType == Variant.Type.Dictionary) + { + // Convert the dictionary to a BsonDocument filter directly + var elemDict = operatorValue.AsGodotDictionary(); + var bsonDoc = new BsonDocument(); + + foreach (var kvp in elemDict) + { + bsonDoc.Add(kvp.Key.ToString(), ConvertToBsonValue(kvp.Value)); + } + + operatorFilter = builder.ElemMatch(fieldName, new BsonDocumentFilterDefinition(bsonDoc)); + } + break; + case "$size": + operatorFilter = builder.Size(fieldName, operatorValue.AsInt32()); + break; + + // Existence operators + case "$exists": + operatorFilter = builder.Exists(fieldName, operatorValue.AsBool()); + break; + case "$type": + // Handle BSON type checking + if (operatorValue.VariantType == Variant.Type.String) + { + var typeString = operatorValue.AsString(); + BsonType bsonType = ConvertStringToBsonType(typeString); + operatorFilter = builder.Type(fieldName, bsonType); + } + else if (operatorValue.VariantType == Variant.Type.Int) + { + operatorFilter = builder.Type(fieldName, (BsonType)operatorValue.AsInt32()); + } + break; + + // Modulo operator + case "$mod": + if (operatorValue.VariantType == Variant.Type.Array) + { + var modArray = operatorValue.AsGodotArray(); + if (modArray.Count == 2) + { + var divisor = modArray[0].AsInt64(); + var remainder = modArray[1].AsInt64(); + operatorFilter = builder.Mod(fieldName, divisor, remainder); + } + } + break; + + // Text search + case "$text": + if (operatorValue.VariantType == Variant.Type.Dictionary) + { + var textDict = operatorValue.AsGodotDictionary(); + if (textDict.ContainsKey("$search")) + { + var searchText = textDict["$search"].AsString(); + var textOptions = new TextSearchOptions(); + + if (textDict.ContainsKey("$language")) + { + textOptions.Language = textDict["$language"].AsString(); + } + if (textDict.ContainsKey("$caseSensitive")) + { + textOptions.CaseSensitive = textDict["$caseSensitive"].AsBool(); + } + if (textDict.ContainsKey("$diacriticSensitive")) + { + textOptions.DiacriticSensitive = textDict["$diacriticSensitive"].AsBool(); + } + + operatorFilter = builder.Text(searchText, textOptions); + } + } + break; + } + + if (operatorFilter != null) + { + filters.Add(operatorFilter); + } + } + + if (filters.Count == 0) + { + return null; + } + else if (filters.Count == 1) + { + return filters[0]; + } + else + { + return builder.And(filters); + } + } + + // Helper method to convert regex options + private string ConvertRegexOptions(RegexOptions options) + { + var result = ""; + if (options.HasFlag(RegexOptions.IgnoreCase)) result += "i"; + if (options.HasFlag(RegexOptions.Multiline)) result += "m"; + if (options.HasFlag(RegexOptions.Singleline)) result += "s"; + return result; + } + + // Helper method to convert string to BsonType + private BsonType ConvertStringToBsonType(string typeString) + { + return typeString.ToLower() switch + { + "double" => BsonType.Double, + "string" => BsonType.String, + "object" => BsonType.Document, + "array" => BsonType.Array, + "bindata" => BsonType.Binary, + "undefined" => BsonType.Undefined, + "objectid" => BsonType.ObjectId, + "bool" => BsonType.Boolean, + "date" => BsonType.DateTime, + "null" => BsonType.Null, + "regex" => BsonType.RegularExpression, + "javascript" => BsonType.JavaScript, + "symbol" => BsonType.Symbol, + "javascriptwithscope" => BsonType.JavaScriptWithScope, + "int" => BsonType.Int32, + "timestamp" => BsonType.Timestamp, + "long" => BsonType.Int64, + "decimal" => BsonType.Decimal128, + "minkey" => BsonType.MinKey, + "maxkey" => BsonType.MaxKey, + _ => BsonType.String + }; + } + // -------------------------------------------------- public Godot.Collections.Array GetDocuments() @@ -72,46 +413,20 @@ public int CountDocuments() public Dictionary GetDocument(String id) { + var output = new Godot.Collections.Dictionary(); try { - FilterDefinition filter; - - - try - { - filter = Builders.Filter.Eq("_id", id); - } - catch (System.Exception) - { - } - finally - { - filter = Builders.Filter.Eq("_id", ObjectId.Parse(id)); - } - - try + var filter = Builders.Filter.Eq("_id", ObjectId.Parse(id)); + var findDocument = BsonCollection.Find(filter).FirstOrDefault(); + if (findDocument != null) { - var findDocument = BsonCollection.Find(filter).First(); return Converters.ConvertBsonDocumentToDictionary(findDocument); - - } - catch(System.Exception) - { } - finally - { - } - - } - catch - { - } - finally + catch (System.Exception ex) { - + GD.PrintErr("[MongoDB Bridge] >> Error in GetDocument: " + ex.Message); } - var output = new Godot.Collections.Dictionary(); return output; } @@ -122,6 +437,92 @@ public Godot.Collections.Array FindDocumentsBy(String key, String va return Converters.ConvertBsonListToJsonList(findDocument); } + // Enhanced FindDocuments method with advanced MongoDB operators + public Godot.Collections.Array FindDocuments(Dictionary filters) + { + try + { + // Return empty array if no filters provided + if (filters == null || filters.Count == 0) + { + return new Godot.Collections.Array(); + } + + // Use the advanced filter builder + var combinedFilter = BuildAdvancedFilter(filters); + + var results = BsonCollection.Find(combinedFilter).ToList(); + return Converters.ConvertBsonListToJsonList(results); + } + catch (System.Exception ex) + { + GD.PrintErr("[MongoDB Bridge] >> Error in FindDocuments: " + ex.Message); + return new Godot.Collections.Array(); + } + } + + // New method for advanced querying with additional options + public Godot.Collections.Array FindDocumentsAdvanced(Dictionary filters, Dictionary options = null) + { + try + { + if (filters == null) + { + filters = new Dictionary(); + } + + var combinedFilter = BuildAdvancedFilter(filters); + var findQuery = BsonCollection.Find(combinedFilter); + + // Handle options + if (options != null) + { + if (options.ContainsKey("limit")) + { + findQuery = findQuery.Limit(options["limit"].AsInt32()); + } + if (options.ContainsKey("skip")) + { + findQuery = findQuery.Skip(options["skip"].AsInt32()); + } + if (options.ContainsKey("sort")) + { + var sortDict = options["sort"].AsGodotDictionary(); + var sortBuilder = Builders.Sort; + var sortDefinitions = new List>(); + + foreach (var sortField in sortDict) + { + var fieldName = sortField.Key.ToString(); + var sortOrder = sortField.Value.AsInt32(); + + var fieldSort = sortOrder == 1 ? sortBuilder.Ascending(fieldName) : sortBuilder.Descending(fieldName); + sortDefinitions.Add(fieldSort); + } + + if (sortDefinitions.Count > 0) + { + // Combine sort definitions manually + SortDefinition combinedSort = sortDefinitions[0]; + for (int i = 1; i < sortDefinitions.Count; i++) + { + combinedSort = sortBuilder.Combine(combinedSort, sortDefinitions[i]); + } + findQuery = findQuery.Sort(combinedSort); + } + } + } + + var results = findQuery.ToList(); + return Converters.ConvertBsonListToJsonList(results); + } + catch (System.Exception ex) + { + GD.PrintErr("[MongoDB Bridge] >> Error in FindDocumentsAdvanced: " + ex.Message); + return new Godot.Collections.Array(); + } + } + public void UpdateDocumentBy(String key, String oldValue, String newValue) { var filter = Builders.Filter.Eq(key, oldValue); @@ -130,6 +531,7 @@ public void UpdateDocumentBy(String key, String oldValue, String newValue) BsonCollection.UpdateOne(filter, update); AutoRetrieveDocument(); } + public void UpdateDocumentsBy(String key, String oldValue, String newValue) { var filter = Builders.Filter.Eq(key, oldValue); @@ -140,16 +542,23 @@ public void UpdateDocumentsBy(String key, String oldValue, String newValue) public void ReplaceOne(String key, String value, Dictionary replacement) { - var filter = Builders.Filter.Eq(key, value); - BsonCollection.ReplaceOne(filter, Converters.ConvertDictionaryToBsonDocument(replacement)); - AutoRetrieveDocument(); + var filter = Builders.Filter.Eq(key, value); + BsonCollection.ReplaceOne(filter, Converters.ConvertDictionaryToBsonDocument(replacement)); + AutoRetrieveDocument(); } public void ReplaceOneByID(String id, Dictionary replacement) { - var filter = Builders.Filter.Eq("_id", ObjectId.Parse(id)); - BsonCollection.ReplaceOne(filter, Converters.ConvertDictionaryToBsonDocument(replacement)); - AutoRetrieveDocument(); + var objectId = ObjectId.Parse(id); + var filter = Builders.Filter.Eq("_id", objectId); + + if (replacement.ContainsKey("_id")) + { + replacement.Remove("_id"); + } + + BsonCollection.ReplaceOne(filter, Converters.ConvertDictionaryToBsonDocument(replacement)); + AutoRetrieveDocument(); } public void DeleteDocumentBy(String key, String value) @@ -172,6 +581,4 @@ public void DeleteDocumentsBy(String key, String value) BsonCollection.DeleteMany(filter); AutoRetrieveDocument(); } - - } diff --git a/addons/MongoDB/MongoDatabase/_MongoDatabase.cs b/addons/MongoDB/MongoDatabase/_MongoDatabase.cs index 52e7375..5e3c1c7 100644 --- a/addons/MongoDB/MongoDatabase/_MongoDatabase.cs +++ b/addons/MongoDB/MongoDatabase/_MongoDatabase.cs @@ -4,62 +4,61 @@ using System.Collections.Generic; using MongoDB.Bson; using MongoDB.Driver; -using MongoDB.Driver.Core; -public class _MongoDatabase : Node +public partial class _MongoDatabase : Node { - private IMongoDatabase database; - private String addonPath; + private IMongoDatabase database; + private String addonPath; - public void LoadDatabase(IMongoDatabase db, String path) - { - database = db; - addonPath = path; - } + public void LoadDatabase(IMongoDatabase db, String path) + { + database = db; + addonPath = path; + } - public Godot.Collections.Array GetCollectionsList() - { - return Converters.ConvertBsonListToArray(database.ListCollections().ToList()); - } - public Godot.Collections.Array GetCollectionsNameList() - { - return Converters.ConvertStringListToArray(database.ListCollectionNames().ToList()); - } + public Godot.Collections.Array GetCollectionsList() + { + return Converters.ConvertBsonListToArray(database.ListCollections().ToList()); + } + public Godot.Collections.Array GetCollectionsNameList() + { + return Converters.ConvertStringListToArray(database.ListCollectionNames().ToList()); + } - public _MongoCollection GetCollection(String collectionName) - { - var collection = database.GetCollection(collectionName); - _MongoCollection CollectionScene = null; - if (!HasNode(collectionName)) { - var MongoCollectionScene = (PackedScene) ResourceLoader.Load(addonPath+"MongoCollection/MongoCollection.tscn"); - CollectionScene = (_MongoCollection)MongoCollectionScene.Instance(); - AddChild(CollectionScene); - CollectionScene.LoadCollection(collection, addonPath); - CollectionScene.Name = collectionName; - } - else { - CollectionScene = (_MongoCollection) GetNode(collectionName); - } - return CollectionScene; - } + public _MongoCollection GetCollection(String collectionName) + { + var collection = database.GetCollection(collectionName); + _MongoCollection CollectionScene = null; + if (!HasNode(collectionName)) { + var MongoCollectionScene = (PackedScene) ResourceLoader.Load(addonPath+"MongoCollection/MongoCollection.tscn"); + CollectionScene = (_MongoCollection)MongoCollectionScene.Instantiate(); + AddChild(CollectionScene); + CollectionScene.LoadCollection(collection, addonPath); + CollectionScene.Name = collectionName; + } + else { + CollectionScene = (_MongoCollection) GetNode(collectionName); + } + return CollectionScene; + } - public _MongoCollection CreateCollection(String collectionName) - { - try - { - database.CreateCollection(collectionName); - } - catch (System.Exception) - { - GD.PrintErr("[MongoDB Bridge] >> A collection named '"+collectionName+"' already exists in the current database. The existing one is returned"); - } - return GetCollection(collectionName); - } + public _MongoCollection CreateCollection(String collectionName) + { + try + { + database.CreateCollection(collectionName); + } + catch (System.Exception) + { + GD.PrintErr("[MongoDB Bridge] >> A collection named '"+collectionName+"' already exists in the current database. The existing one is returned"); + } + return GetCollection(collectionName); + } - public void DropCollection(String collectionName) - { - database.DropCollection(collectionName); - } + public void DropCollection(String collectionName) + { + database.DropCollection(collectionName); + } } diff --git a/addons/MongoDB/MongoDocument/MongoDocument.tscn b/addons/MongoDB/MongoDocument/MongoDocument.tscn index 8d7b50e..c8acdbf 100644 --- a/addons/MongoDB/MongoDocument/MongoDocument.tscn +++ b/addons/MongoDB/MongoDocument/MongoDocument.tscn @@ -1,6 +1,6 @@ -[gd_scene load_steps=2 format=2] +[gd_scene load_steps=2 format=3 uid="uid://ip33jqxd27qn"] -[ext_resource path="res://addons/MongoDB/MongoDocument/_MongoDocument.cs" type="Script" id=1] +[ext_resource type="Script" uid="uid://desysi5gynp2g" path="res://addons/MongoDB/MongoDocument/_MongoDocument.cs" id="1"] [node name="MongoDocument" type="Node"] -script = ExtResource( 1 ) +script = ExtResource("1") diff --git a/addons/MongoDB/MongoDocument/_MongoDocument.cs b/addons/MongoDB/MongoDocument/_MongoDocument.cs index 2a0fb08..32bd115 100644 --- a/addons/MongoDB/MongoDocument/_MongoDocument.cs +++ b/addons/MongoDB/MongoDocument/_MongoDocument.cs @@ -1,9 +1,9 @@ using Godot; using System; -public class _MongoDocument : Node +public partial class _MongoDocument : Node { - - + + } diff --git a/addons/MongoDB/Utils/Converters.cs b/addons/MongoDB/Utils/Converters.cs index 166dfa4..53adf14 100644 --- a/addons/MongoDB/Utils/Converters.cs +++ b/addons/MongoDB/Utils/Converters.cs @@ -1,63 +1,95 @@ -using Godot; -using Godot.Collections; -using System; -using System.Linq; -using System.Collections.Generic; -using MongoDB.Bson; -using MongoDB.Bson.IO; -using MongoDB.Driver; -using MongoDB.Driver.Core; - -public static class Converters -{ - - public static String ConvertBsonDocumentToString(BsonDocument BsonDocument) - { - return BsonDocument.ToString(); - } - - public static Dictionary ConvertBsonDocumentToDictionary(BsonDocument BsonDocument) - { - var jsonWriterSettings = new JsonWriterSettings { OutputMode = JsonOutputMode.Strict }; - var jsonStringDocument = BsonDocument.ToJson(jsonWriterSettings); - var jsonDocument = JSON.Parse(jsonStringDocument).Result; - return (Dictionary) jsonDocument; - } - - public static BsonDocument ConvertDictionaryToBsonDocument(Dictionary dictionary) - { - var documentString = JSON.Print(dictionary); - var BSONdocument = BsonDocument.Parse(documentString); - return BSONdocument; - } - - public static Godot.Collections.Array ConvertBsonListToArray(List bsonList) - { - var array = new Godot.Collections.Array(); - foreach (BsonDocument bson in bsonList) - { - array.Add(ConvertBsonDocumentToString(bson)); - } - return array; - } - - public static Godot.Collections.Array ConvertBsonListToJsonList(List bsonList) - { - var array = new Godot.Collections.Array(); - foreach (BsonDocument bson in bsonList) - array.Add(ConvertBsonDocumentToDictionary(bson)); - return array; - } - - public static Godot.Collections.Array ConvertStringListToArray(List stringList) - { - var array = new Godot.Collections.Array(); - foreach (String _string in stringList) - { - array.Add(_string); - } - return array; - } - - -} \ No newline at end of file +using Godot; +using Godot.Collections; +using System; +using System.Linq; +using System.Collections.Generic; +using MongoDB.Bson; +using MongoDB.Bson.IO; +using MongoDB.Driver; + +public static class Converters +{ + + public static String ConvertBsonDocumentToString(BsonDocument BsonDocument) + { + return BsonDocument.ToString(); + } + + public static Dictionary ConvertBsonDocumentToDictionary(BsonDocument BsonDocument) + { + var result = new Dictionary(); + foreach (var element in BsonDocument.Elements) + { + Variant value = ConvertBsonValue(element.Value); + result[element.Name] = value; + } + return result; + } + + private static Variant ConvertBsonValue(BsonValue value) + { + switch (value.BsonType) + { + case BsonType.Int32: + return value.AsInt32; + case BsonType.Int64: + return value.AsInt64; + case BsonType.Double: + return value.AsDouble; + case BsonType.String: + return value.AsString; + case BsonType.Boolean: + return value.AsBoolean; + case BsonType.Array: + var array = new Godot.Collections.Array(); + foreach (var item in value.AsBsonArray) + { + array.Add(ConvertBsonValue(item)); + } + return array; + case BsonType.Document: + return ConvertBsonDocumentToDictionary(value.AsBsonDocument); + case BsonType.Null: + return default; + default: + return value.ToString(); + } + } + + public static BsonDocument ConvertDictionaryToBsonDocument(Dictionary dictionary) + { + var documentString = Json.Stringify(dictionary); + var BSONdocument = BsonDocument.Parse(documentString); + return BSONdocument; + } + + public static Godot.Collections.Array ConvertBsonListToArray(List bsonList) + { + var array = new Godot.Collections.Array(); + foreach (BsonDocument bson in bsonList) + { + array.Add(ConvertBsonDocumentToString(bson)); + } + return array; + } + + public static Godot.Collections.Array ConvertBsonListToJsonList(List bsonList) + { + var array = new Godot.Collections.Array(); + foreach (BsonDocument bson in bsonList) + array.Add(ConvertBsonDocumentToDictionary(bson)); + return array; + } + + public static Godot.Collections.Array ConvertStringListToArray(List stringList) + { + var array = new Godot.Collections.Array(); + foreach (String _string in stringList) + { + array.Add(_string); + } + return array; + } + + +} diff --git a/addons/MongoDB/mongoDB-icon.png.import b/addons/MongoDB/mongoDB-icon.png.import index dd2dbaa..97293a8 100644 --- a/addons/MongoDB/mongoDB-icon.png.import +++ b/addons/MongoDB/mongoDB-icon.png.import @@ -1,8 +1,9 @@ [remap] importer="texture" -type="StreamTexture" -path="res://.import/mongoDB-icon.png-f4dd11bef468ad5decdab4e5ea70b270.stex" +type="CompressedTexture2D" +uid="uid://dv3crnf1ogut2" +path="res://.godot/imported/mongoDB-icon.png-f4dd11bef468ad5decdab4e5ea70b270.ctex" metadata={ "vram_texture": false } @@ -10,25 +11,24 @@ metadata={ [deps] source_file="res://addons/MongoDB/mongoDB-icon.png" -dest_files=[ "res://.import/mongoDB-icon.png-f4dd11bef468ad5decdab4e5ea70b270.stex" ] +dest_files=["res://.godot/imported/mongoDB-icon.png-f4dd11bef468ad5decdab4e5ea70b270.ctex"] [params] compress/mode=0 +compress/high_quality=false compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/bptc_ldr=0 +compress/hdr_compression=1 compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" process/fix_alpha_border=true process/premult_alpha=false -process/HDR_as_SRGB=false -process/invert_color=false -stream=false -size_limit=0 -detect_3d=true -svg/scale=1.0 +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/MongoDB/mongodb-bridge-icon.png.import b/addons/MongoDB/mongodb-bridge-icon.png.import new file mode 100644 index 0000000..a7ab707 --- /dev/null +++ b/addons/MongoDB/mongodb-bridge-icon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c1b5oslujtvtf" +path="res://.godot/imported/mongodb-bridge-icon.png-ceab99b0f6e691159c59d8651b5d9f04.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/MongoDB/mongodb-bridge-icon.png" +dest_files=["res://.godot/imported/mongodb-bridge-icon.png-ceab99b0f6e691159c59d8651b5d9f04.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/addons/MongoDB/mongodb-bridge.gd b/addons/MongoDB/mongodb-bridge.gd index decbe67..f4cda0d 100644 --- a/addons/MongoDB/mongodb-bridge.gd +++ b/addons/MongoDB/mongodb-bridge.gd @@ -1,4 +1,4 @@ -tool +@tool extends EditorPlugin var _MongoAPI : String = ("res://addons/MongoDB/MongoAPI.cs") var _MongoClient : String = ("res://addons/MongoDB/MongoClient/_MongoClient.cs") @@ -7,13 +7,13 @@ var _MongoCollection : String = ("res://addons/MongoDB/MongoCollection/_MongoCol func _enter_tree(): - add_autoload_singleton("MongoAPI",_MongoAPI) - add_autoload_singleton("MongoClient",_MongoClient) - add_autoload_singleton("MongoDatabase",_MongoDatabase) - add_autoload_singleton("MongoCollection",_MongoCollection) + add_autoload_singleton("MongoAPI",_MongoAPI) + add_autoload_singleton("MongoClient",_MongoClient) + add_autoload_singleton("MongoDatabase",_MongoDatabase) + add_autoload_singleton("MongoCollection",_MongoCollection) func _exit_tree(): - remove_autoload_singleton("MongoAPI") - remove_autoload_singleton("MongoClient") - remove_autoload_singleton("MongoDatabase") - remove_autoload_singleton("MongoCollection") + remove_autoload_singleton("MongoAPI") + remove_autoload_singleton("MongoClient") + remove_autoload_singleton("MongoDatabase") + remove_autoload_singleton("MongoCollection")