Skip to content

Commit c6a8754

Browse files
authored
feat: Complete Google Cloud Firestore integration (#30)
1 parent aee6564 commit c6a8754

9 files changed

Lines changed: 731 additions & 32 deletions

File tree

README.md

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ The module structure exactly mirrors the Eclipse Store Java repository for famil
3636
| `afs/blobstore` | `afs/blobstore/` | ✅ Complete |
3737
| `afs/aws/s3` | `afs/aws/s3/` | ✅ Complete |
3838
| `afs/azure/storage` | `afs/azure/storage/` | ✅ Complete |
39-
| `afs/googlecloud/firestore` | `afs/googlecloud/firestore/` | 🚧 In Progress |
39+
| `afs/googlecloud/firestore` | `afs/googlecloud/firestore/` | ✅ Complete |
4040
| `gigamap/gigamap` | `gigamap/` | ✅ Complete |
4141

4242
## 🚧 Eclipse Store Migration Progress
@@ -80,7 +80,7 @@ This project ports code from the [Eclipse Store Java repository](https://github.
8080
- **Java Source**: [`afs/blobstore`](https://github.com/eclipse-store/store/tree/main/afs/blobstore)**C# Port**: `afs/blobstore/`
8181
- **Java Source**: [`afs/aws/s3`](https://github.com/eclipse-store/store/tree/main/afs/aws/s3)**C# Port**: `afs/aws/s3/`
8282
- **Java Source**: [`afs/azure/storage`](https://github.com/eclipse-store/store/tree/main/afs/azure/storage)**C# Port**: `afs/azure/storage/`
83-
- **Java Source**: [`afs/googlecloud/firestore`](https://github.com/eclipse-store/store/tree/main/afs/googlecloud/firestore)**C# Port**: `afs/googlecloud/firestore/` (in progress)
83+
- **Java Source**: [`afs/googlecloud/firestore`](https://github.com/eclipse-store/store/tree/main/afs/googlecloud/firestore)**C# Port**: `afs/googlecloud/firestore/`
8484
- **Java Source**: [`gigamap/gigamap`](https://github.com/eclipse-store/store/tree/main/gigamap/gigamap)**C# Port**: `gigamap/`
8585

8686
The .NET implementation maintains the same module structure, interfaces, and design patterns as the original Eclipse Store Java code while adapting to .NET conventions and leveraging C# language features.
@@ -157,8 +157,8 @@ NebulaStore follows the Eclipse Store module structure:
157157
- **src/** - Azure Storage connector and extensions
158158
- **test/** - Azure Storage integration tests
159159
- **NebulaStore.Afs.Azure.Storage.csproj** - Project file
160-
- **googlecloud/** - Google Cloud storage backends (in progress)
161-
- **firestore/** - Google Cloud Firestore integration (in progress)
160+
- **googlecloud/** - Google Cloud storage backends
161+
- **firestore/** - Google Cloud Firestore integration
162162
- **src/** - Firestore connector and extensions
163163
- **test/** - Firestore integration tests
164164
- **NebulaStore.Afs.GoogleCloud.Firestore.csproj** - Project file
@@ -339,6 +339,25 @@ var azureConfig = EmbeddedStorageConfiguration.New()
339339
using var azureStorage = EmbeddedStorage.Foundation(azureConfig).Start();
340340
```
341341

342+
#### Google Cloud Firestore Usage
343+
344+
```csharp
345+
using NebulaStore.Afs.GoogleCloud.Firestore;
346+
using NebulaStore.Storage.Embedded;
347+
using NebulaStore.Storage.EmbeddedConfiguration;
348+
349+
// Start with Google Cloud Firestore
350+
using var storage = EmbeddedStorage.StartWithFirestore("your-project-id");
351+
352+
// Custom Firestore configuration
353+
var firestoreConfig = EmbeddedStorageConfiguration.New()
354+
.UseFirestore("your-project-id", "my-storage", useCache: true)
355+
.SetChannelCount(4)
356+
.Build();
357+
358+
using var firestoreStorage = EmbeddedStorage.Foundation(firestoreConfig).Start();
359+
```
360+
342361
#### Custom Root Object
343362
```csharp
344363
var myRoot = new MyDataClass { SomeProperty = "initial" };
@@ -407,6 +426,15 @@ The `examples/` directory contains comprehensive examples demonstrating NebulaSt
407426
- Crash recovery and data integrity validation
408427
- Transaction logging and performance monitoring
409428

429+
### ☁️ Cloud Storage Examples
430+
- **`FirestoreExample.cs`** - **NEW!** Google Cloud Firestore integration including:
431+
- Simple Firestore storage setup and configuration
432+
- Configuration-based approach with custom settings
433+
- Direct AFS usage for advanced scenarios
434+
- Batch operations and large object handling
435+
- **`AzureStorageExample.cs`** - Azure Storage backend demonstrations
436+
- **`S3Example.cs`** - AWS S3 storage backend examples
437+
410438
### 🔍 Advanced Querying Examples
411439
- **`GigaMapAdvancedExample.cs`** - **NEW!** Advanced features including:
412440
- Eclipse Store compatible `GigaMap.Builder<T>()` API

afs/googlecloud/firestore/README.md

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,65 @@ You must also have:
2525
### Basic Usage
2626

2727
```csharp
28-
using Google.Cloud.Firestore;
29-
using NebulaStore.Afs.GoogleCloud.Firestore;
3028
using NebulaStore.Storage.Embedded;
3129

32-
// Create Firestore connection
33-
var firestore = FirestoreDb.Create("your-project-id");
30+
// Simple Firestore storage - easiest way to get started
31+
using var storage = EmbeddedStorage.StartWithFirestore("your-project-id");
32+
33+
// Use storage normally
34+
var root = storage.Root<MyDataClass>();
35+
if (root == null)
36+
{
37+
root = new MyDataClass { SomeProperty = "value" };
38+
storage.SetRoot(root);
39+
}
40+
else
41+
{
42+
root.SomeProperty = "updated value";
43+
}
44+
storage.StoreRoot();
45+
```
3446

35-
// Create AFS configuration with Firestore
47+
### Configuration-Based Usage
48+
49+
```csharp
50+
using NebulaStore.Afs.GoogleCloud.Firestore;
51+
using NebulaStore.Storage.Embedded;
52+
using NebulaStore.Storage.EmbeddedConfiguration;
53+
54+
// Using configuration builder with Firestore extension
3655
var config = EmbeddedStorageConfiguration.New()
37-
.SetStorageDirectory("firestore-storage")
38-
.SetUseAfs(true)
39-
.SetAfsStorageType("firestore")
40-
.SetAfsConnectionString("your-project-id")
56+
.UseFirestore("your-project-id", "my-storage", useCache: true)
57+
.SetChannelCount(4)
4158
.Build();
4259

43-
using var storage = EmbeddedStorage.StartWithAfs(config);
60+
using var storage = EmbeddedStorage.Foundation(config).Start();
4461

4562
// Use storage normally
4663
var root = storage.Root<MyDataClass>();
4764
root.SomeProperty = "value";
4865
storage.StoreRoot();
4966
```
5067

68+
### Alternative Convenience Methods
69+
70+
```csharp
71+
using NebulaStore.Afs.GoogleCloud.Firestore;
72+
73+
// Using the Firestore extensions directly
74+
using var storage1 = EmbeddedStorageFirestoreExtensions.StartWithFirestore("your-project-id");
75+
76+
// With a root object
77+
var myData = new MyDataClass { SomeProperty = "initial value" };
78+
using var storage2 = EmbeddedStorageFirestoreExtensions.StartWithFirestore(myData, "your-project-id");
79+
80+
// With custom settings
81+
using var storage3 = EmbeddedStorageFirestoreExtensions.StartWithFirestore(
82+
"your-project-id",
83+
"custom-storage-name",
84+
useCache: false);
85+
```
86+
5187
### Direct AFS Usage
5288

5389
```csharp

afs/googlecloud/firestore/examples/FirestoreExample.cs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,48 @@ public class Person
2121
public string Email { get; set; } = string.Empty;
2222
}
2323

24+
/// <summary>
25+
/// Example using the simple convenience method.
26+
/// </summary>
27+
public static void SimpleFirestoreExample()
28+
{
29+
Console.WriteLine("=== Simple Firestore Example ===");
30+
31+
try
32+
{
33+
// Start storage with Firestore backend - simplest approach
34+
using var storage = EmbeddedStorage.StartWithFirestore("your-project-id");
35+
36+
// Create and store data
37+
var root = storage.Root<Person>();
38+
if (root == null)
39+
{
40+
root = new Person
41+
{
42+
Name = "Alice Smith",
43+
Age = 28,
44+
Email = "alice.smith@example.com"
45+
};
46+
storage.SetRoot(root);
47+
}
48+
else
49+
{
50+
root.Age = 29; // Birthday!
51+
}
52+
53+
storage.StoreRoot();
54+
Console.WriteLine($"Stored person: {root.Name}, Age: {root.Age}");
55+
}
56+
catch (Exception ex)
57+
{
58+
Console.WriteLine($"Error: {ex.Message}");
59+
Console.WriteLine("Make sure you have:");
60+
Console.WriteLine("1. A Google Cloud Project with Firestore enabled");
61+
Console.WriteLine("2. Proper authentication configured");
62+
Console.WriteLine("3. The Google.Cloud.Firestore package installed");
63+
}
64+
}
65+
2466
/// <summary>
2567
/// Example using the configuration-based approach.
2668
/// </summary>
@@ -37,7 +79,7 @@ public static void ConfigurationBasedExample()
3779

3880
try
3981
{
40-
// Start storage with Firestore backend
82+
// Start storage with Firestore backend using configuration
4183
using var storage = EmbeddedStorage.Foundation(config).Start();
4284

4385
// Create and store data

afs/googlecloud/firestore/src/EmbeddedStorageFirestoreExtensions.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,25 @@ public static IEmbeddedStorageManager StartWithFirestore(
2323
string? storageDirectory = null,
2424
bool useCache = true)
2525
{
26-
// For now, we'll use the standard embedded storage with a note that
27-
// full Firestore integration requires additional setup
26+
if (string.IsNullOrEmpty(projectId))
27+
throw new ArgumentException("Project ID cannot be null or empty", nameof(projectId));
28+
29+
// Create configuration with Firestore AFS backend
2830
var config = EmbeddedStorageConfiguration.New()
2931
.SetStorageDirectory(storageDirectory ?? "firestore-storage")
32+
.SetUseAfs(true)
33+
.SetAfsStorageType("firestore")
34+
.SetAfsConnectionString(projectId)
35+
.SetAfsUseCache(useCache)
3036
.Build();
3137

32-
// TODO: Implement full Firestore integration with custom storage connection
33-
// For now, this creates a standard storage manager
38+
// Start with AFS using Firestore connector
3439
return EmbeddedStorage.Foundation(config).Start();
3540
}
3641

3742
/// <summary>
3843
/// Creates and starts an embedded storage manager with Google Cloud Firestore and root object.
39-
/// Note: This creates a storage manager that uses Firestore directly, bypassing the standard AFS system.
44+
/// This method configures the storage to use Firestore as the backend through the AFS system.
4045
/// </summary>
4146
/// <param name="root">The root object</param>
4247
/// <param name="projectId">The Google Cloud Project ID</param>
@@ -49,10 +54,19 @@ public static IEmbeddedStorageManager StartWithFirestore(
4954
string? storageDirectory = null,
5055
bool useCache = true)
5156
{
57+
if (string.IsNullOrEmpty(projectId))
58+
throw new ArgumentException("Project ID cannot be null or empty", nameof(projectId));
59+
60+
// Create configuration with Firestore AFS backend
5261
var config = EmbeddedStorageConfiguration.New()
5362
.SetStorageDirectory(storageDirectory ?? "firestore-storage")
63+
.SetUseAfs(true)
64+
.SetAfsStorageType("firestore")
65+
.SetAfsConnectionString(projectId)
66+
.SetAfsUseCache(useCache)
5467
.Build();
5568

69+
// Start with AFS using Firestore connector
5670
return EmbeddedStorage.Foundation(config).Start(root);
5771
}
5872

afs/googlecloud/firestore/src/FirestoreConfigurationExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using NebulaStore.Storage.EmbeddedConfiguration;
23

34
namespace NebulaStore.Afs.GoogleCloud.Firestore;

0 commit comments

Comments
 (0)