Skip to content

Commit ffea0ba

Browse files
ermartinez13GitHub Actionsfplaras
authored
Seed database (#5)
* install faker package * create listing model * create listing factory method * wip * fix: set person-address two way key to null * define person and address models * add methods to generate fake addresses and persons * refactor: create temp abstractions for main logic * add `GetPeople` method to faker factory * create data factory and data generator abstractions * add get serialized person and address methods * add appwrite service method to update doc * get documents supports queries * convert docment to person type * refactor: listing model types for available date and housing type * generate serialized listing instance * define user model * add GetUser method to data factory * generate a serialized user instance * convert User json to model instance * enable conversion of address and listing documents to typed objects * add methods to data factory for generating multiple instances * refactor: DataGenerator to DatabaseSeeder encapsulates getting instaces from data factory and uploading to appwrite * generate between 0 and 3 listings per user * fix: max values for listing's price and bedrooms * implement SeedCollections * remove Serialize() and CreateDocument() duplication * seed database * add documentation comments to DatabaseSeeder class * rename DataGenerator.cs to DatabaseSeeder.cs * fix: non-nullable warning for string properties * test: faker factory model instantiation * rename DataFactory class and filename to reflect interface status * fix: missing faker factory namespace directive * test: seeding of collections * fix: appwrite interface casting with wrapper class * Apply code formatting * added directory path * fix: set the console app project directory --------- Co-authored-by: GitHub Actions <github-actions@github.com> Co-authored-by: Frank Perez <1815587+fplaras@users.noreply.github.com> Co-authored-by: Erick Martinez <>
1 parent cf29ce6 commit ffea0ba

15 files changed

+591
-57
lines changed

AppwriteClient/AppwriteService.cs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,11 @@ public async Task<CollectionList> GetCollectionList(string databaseId)
231231
return collectionList;
232232
}
233233

234-
public async Task<DocumentList> GetDocuments(string databaseId, string collectionId)
234+
public async Task<DocumentList> GetDocuments(string databaseId, string collectionId, List<string>? queries = null)
235235
{
236236
try
237237
{
238-
var documents = await databaseClient.ListDocuments(databaseId, collectionId);
238+
var documents = await databaseClient.ListDocuments(databaseId, collectionId, queries);
239239
return documents;
240240
}
241241
catch (Exception ex)
@@ -245,6 +245,7 @@ public async Task<DocumentList> GetDocuments(string databaseId, string collectio
245245
}
246246

247247
}
248+
248249
//public async Task GetDocuments(string databaseId, string collectionId)
249250
//{
250251
// List<string> queries = new List<string>();
@@ -264,6 +265,35 @@ public async Task<DocumentList> GetDocuments(string databaseId, string collectio
264265
// }
265266

266267
//}
268+
269+
public async Task<Document> CreateDocument(string databaseId, string collectionId, object data, string? documentId = null)
270+
{
271+
string docId = documentId ?? ID.Unique();
272+
try
273+
{
274+
var document = await databaseClient.CreateDocument(databaseId, collectionId, docId, data);
275+
return document;
276+
}
277+
catch (Exception ex)
278+
{
279+
280+
throw;
281+
}
282+
}
283+
284+
public async Task<Document> UpdateDocument(string databaseId, string collectionId, string documentId, object data)
285+
{
286+
try
287+
{
288+
var document = await databaseClient.UpdateDocument(databaseId, collectionId, documentId, data);
289+
return document;
290+
}
291+
catch (Exception ex)
292+
{
293+
294+
throw;
295+
}
296+
}
267297
}
268298

269299
/// <summary>

AppwriteConsole.App/AppwriteConsole.App.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
</ItemGroup>
1818

1919
<ItemGroup>
20+
<PackageReference Include="Faker.Net" Version="2.0.163" />
2021
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
2122
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
2223
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="6.0.1" />

AppwriteConsole.App/DDL/housingsearch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
"Type": "oneToOne",
112112
"TwoWay": false,
113113
"Key": "AddressId",
114-
"TwoWayKey": "Id",
114+
"TwoWayKey": null,
115115
"OnDelete": "cascade"
116116
}
117117
]
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Helpers;
2+
using AppwriteClient;
3+
4+
namespace Helpers;
5+
6+
class AppwriteServiceWrapper : IBackendService
7+
{
8+
private AppwriteService _appwriteService;
9+
10+
public AppwriteServiceWrapper(AppwriteService appwriteService)
11+
{
12+
_appwriteService = appwriteService;
13+
}
14+
15+
public async Task<object> CreateDocument(string databaseId, string collectionId, string itemJson)
16+
{
17+
var result = await _appwriteService.CreateDocument(databaseId, collectionId, itemJson);
18+
return result;
19+
}
20+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
using System.Text.Json;
2+
using System.Text.Json.Serialization;
3+
using AppwriteClient;
4+
using Models;
5+
6+
namespace Helpers;
7+
8+
/// <summary>
9+
/// The <c>DatabaseSeeder</c> class is responsible for seeding various collections in the database.
10+
/// It uses a <see cref="IDataFactory"/> to generate data and an <see cref="AppwriteService"/> to interact with the Appwrite backend.
11+
/// </summary>
12+
public class DatabaseSeeder
13+
{
14+
private IDataFactory _dataFactory;
15+
private IBackendService _appwriteService;
16+
private string _databaseId;
17+
private string _personCollectionId = "person";
18+
private string _addressCollectionId = "address";
19+
private string _listingCollectionId = "listings";
20+
private string _userCollectionId = "users";
21+
22+
/// <summary>
23+
/// Initializes a new instance of the <see cref="DatabaseSeeder"/> class.
24+
/// </summary>
25+
/// <param name="dataFactory">The data factory used to generate data.</param>
26+
/// <param name="appwriteService">The Appwrite service used to interact with the backend.</param>
27+
/// <param name="databaseId">The ID of the database to seed.</param>
28+
public DatabaseSeeder(IDataFactory dataFactory, IBackendService appwriteService, string databaseId)
29+
{
30+
_dataFactory = dataFactory;
31+
_appwriteService = appwriteService;
32+
_databaseId = databaseId;
33+
}
34+
35+
public async Task<List<Person>> SeedPeople(int numberOfPeople)
36+
{
37+
List<Person> people = _dataFactory.GetPeople(numberOfPeople);
38+
List<Task> tasks = new();
39+
foreach (Person person in people)
40+
{
41+
Task task = SerializeAndCreate(person, _personCollectionId);
42+
tasks.Add(task);
43+
}
44+
await Task.WhenAll(tasks);
45+
return people;
46+
}
47+
48+
private Task<object> SerializeAndCreate(object item, string collectionId, JsonSerializerOptions? serializationOptions = null)
49+
{
50+
string itemJson = JsonSerializer.Serialize(item, serializationOptions);
51+
return _appwriteService.CreateDocument(_databaseId, collectionId, itemJson);
52+
}
53+
54+
public async Task<Person> SeedPerson()
55+
{
56+
Person person = _dataFactory.GetPerson();
57+
await SerializeAndCreate(person, _personCollectionId);
58+
return person;
59+
}
60+
61+
public async Task<Address> SeedAddress()
62+
{
63+
Address address = _dataFactory.GetAddress();
64+
await SerializeAndCreate(address, _addressCollectionId);
65+
return address;
66+
}
67+
68+
public async Task<Listing> SeedListing()
69+
{
70+
Listing listing = _dataFactory.GetListing();
71+
var options = new JsonSerializerOptions
72+
{
73+
Converters = { new JsonStringEnumConverter() },
74+
};
75+
await SerializeAndCreate(listing, _listingCollectionId, options);
76+
return listing;
77+
}
78+
79+
public async Task<User> SeedUser()
80+
{
81+
User user = this._dataFactory.GetUser();
82+
var options = new JsonSerializerOptions
83+
{
84+
Converters = { new JsonStringEnumConverter() },
85+
};
86+
await SerializeAndCreate(user, _userCollectionId, options);
87+
return user;
88+
}
89+
90+
public async Task<List<User>> SeedUsers(int numberOfUsers)
91+
{
92+
List<User> users = _dataFactory.GetUsers(numberOfUsers);
93+
List<Task> tasks = new();
94+
foreach (User user in users)
95+
{
96+
var options = new JsonSerializerOptions
97+
{
98+
Converters = { new JsonStringEnumConverter() },
99+
};
100+
Task task = SerializeAndCreate(user, _userCollectionId, options);
101+
tasks.Add(task);
102+
}
103+
await Task.WhenAll(tasks);
104+
return users;
105+
}
106+
107+
public async Task<Dictionary<string, object>> SeedCollections(int numberOfRecords)
108+
{
109+
Dictionary<string, object> collectionItems = new()
110+
{
111+
{ _personCollectionId, await SeedPeople(numberOfRecords) },
112+
{ _userCollectionId, await SeedUsers(numberOfRecords) }
113+
};
114+
return collectionItems;
115+
}
116+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
using Faker;
2+
using FakerBoolean = Faker.Boolean;
3+
using FakerAddress = Faker.Address;
4+
using Models;
5+
using Helpers;
6+
7+
namespace Helpers;
8+
public class FakerFactory : IDataFactory
9+
{
10+
public Listing GetListing()
11+
{
12+
var listing = new Listing
13+
{
14+
Title = Lorem.Sentence(3),
15+
Description = Lorem.Paragraph(2),
16+
Location = FakerAddress.City(),
17+
Price = RandomNumber.Next(0, 1000000),
18+
Bedrooms = RandomNumber.Next(1, 10),
19+
PetsAllowed = FakerBoolean.Random(),
20+
ParkingAvailable = FakerBoolean.Random(),
21+
AvailableDate = DateTime.Now.AddDays(RandomNumber.Next(0, 365)),
22+
HousingType = (HousingType)RandomNumber.Next(0, 1) // Randomly selects between "Apt" and "House"
23+
};
24+
25+
return listing;
26+
}
27+
28+
public List<Listing> GetListings(int numberOfListings)
29+
{
30+
List<Listing> listings = new List<Listing>();
31+
32+
for (int i = 0; i < numberOfListings; i++)
33+
{
34+
listings.Add(GetListing());
35+
}
36+
37+
return listings;
38+
}
39+
40+
public Models.Address GetAddress()
41+
{
42+
var address = new Models.Address
43+
{
44+
Id = Guid.NewGuid().ToString(),
45+
StreetAddress1 = FakerAddress.StreetAddress(),
46+
StreetAddress2 = RandomNumber.Next(0, 1) == 0 ? FakerAddress.SecondaryAddress() : null,
47+
City = FakerAddress.City(),
48+
State = FakerAddress.UsState(),
49+
Zip = FakerAddress.ZipCode(),
50+
County = FakerAddress.UkCounty(),
51+
};
52+
53+
return address;
54+
}
55+
56+
public List<Models.Address> GetAddresses(int numberOfAddresses)
57+
{
58+
List<Models.Address> addresses = new List<Models.Address>();
59+
60+
for (int i = 0; i < numberOfAddresses; i++)
61+
{
62+
addresses.Add(GetAddress());
63+
}
64+
65+
return addresses;
66+
}
67+
68+
public Person GetPerson()
69+
{
70+
var person = new Person
71+
{
72+
FirstName = Name.First(),
73+
LastName = Name.Last(),
74+
Email = Internet.Email(),
75+
Phone = Phone.Number(),
76+
AccountId = Guid.NewGuid().ToString(),
77+
AddressId = GetAddress()
78+
};
79+
80+
return person;
81+
}
82+
83+
public List<Person> GetPeople(int numberOfPeople)
84+
{
85+
List<Person> people = new List<Person>();
86+
87+
for (int i = 0; i < numberOfPeople; i++)
88+
{
89+
people.Add(GetPerson());
90+
}
91+
92+
return people;
93+
}
94+
95+
public User GetUser()
96+
{
97+
User user = new User
98+
{
99+
FirstName = Name.First(),
100+
LastName = Name.Last(),
101+
Email = Internet.Email(),
102+
};
103+
int numberOfListings = RandomNumber.Next(0, 3);
104+
List<Listing> listings = GetListings(numberOfListings);
105+
user.Listings = listings;
106+
return user;
107+
}
108+
109+
public List<User> GetUsers(int numberOfUsers)
110+
{
111+
List<User> users = new List<User>();
112+
113+
for (int i = 0; i < numberOfUsers; i++)
114+
{
115+
users.Add(GetUser());
116+
}
117+
118+
return users;
119+
}
120+
121+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace Helpers;
2+
3+
public interface IBackendService
4+
{
5+
public Task<object> CreateDocument(string databaseId, string collectionId, string itemJson);
6+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Models;
2+
3+
namespace Helpers;
4+
5+
public interface IDataFactory
6+
{
7+
Listing GetListing();
8+
List<Listing> GetListings(int numberOfListings);
9+
Address GetAddress();
10+
List<Address> GetAddresses(int numberOfAddresses);
11+
Person GetPerson();
12+
List<Person> GetPeople(int numberOfPeople);
13+
User GetUser();
14+
List<User> GetUsers(int numberOfUsers);
15+
}

0 commit comments

Comments
 (0)