Skip to content

Commit

Permalink
Merge pull request #391 from notion-dotnet/feature/375-support-queryi…
Browse files Browse the repository at this point in the history
…ng-wiki-databases

Add support for querying wiki databases
  • Loading branch information
KoditkarVedant committed Oct 13, 2023
2 parents 95d0b68 + 8236df3 commit b422493
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 27 deletions.
24 changes: 2 additions & 22 deletions Src/Notion.Client/Api/Databases/DatabasesClient.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading;
using System.Threading.Tasks;
using static Notion.Client.ApiEndpoints;

namespace Notion.Client
{
public class DatabasesClient : IDatabasesClient
public sealed partial class DatabasesClient : IDatabasesClient
{
private readonly IRestClient _client;

Expand All @@ -20,24 +18,6 @@ public async Task<Database> RetrieveAsync(string databaseId, CancellationToken c
return await _client.GetAsync<Database>(DatabasesApiUrls.Retrieve(databaseId), cancellationToken: cancellationToken);
}

public async Task<PaginatedList<Page>> QueryAsync(
string databaseId,
DatabasesQueryParameters databasesQueryParameters, CancellationToken cancellationToken = default)
{
var body = (IDatabaseQueryBodyParameters)databasesQueryParameters;
var queryParameters = (IDatabaseQueryQueryParameters)databasesQueryParameters;

var queryParams = queryParameters.FilterProperties?
.Select(x => new KeyValuePair<string, string>("filter_properties", x));

return await _client.PostAsync<PaginatedList<Page>>(
DatabasesApiUrls.Query(databaseId),
body,
queryParams,
cancellationToken: cancellationToken
);
}

public async Task<Database> CreateAsync(DatabasesCreateParameters databasesCreateParameters, CancellationToken cancellationToken = default)
{
var body = (IDatabasesCreateBodyParameters)databasesCreateParameters;
Expand Down
2 changes: 1 addition & 1 deletion Src/Notion.Client/Api/Databases/IDatabasesClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public interface IDatabasesClient
/// <returns>
/// <see cref="PaginatedList{T}" />
/// </returns>
Task<PaginatedList<Page>> QueryAsync(string databaseId, DatabasesQueryParameters databasesQueryParameters, CancellationToken cancellationToken = default);
Task<DatabaseQueryResponse> QueryAsync(string databaseId, DatabasesQueryParameters databasesQueryParameters, CancellationToken cancellationToken = default);

/// <summary>
/// Creates a database as a subpage in the specified parent page, with the specified properties schema.
Expand Down
28 changes: 28 additions & 0 deletions Src/Notion.Client/Api/Databases/Query/DatabasesClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Notion.Client
{
public sealed partial class DatabasesClient
{
public async Task<DatabaseQueryResponse> QueryAsync(
string databaseId,
DatabasesQueryParameters databasesQueryParameters, CancellationToken cancellationToken = default)
{
var body = (IDatabaseQueryBodyParameters)databasesQueryParameters;
var queryParameters = (IDatabaseQueryQueryParameters)databasesQueryParameters;

var queryParams = queryParameters.FilterProperties?
.Select(x => new KeyValuePair<string, string>("filter_properties", x));

return await _client.PostAsync<DatabaseQueryResponse>(
ApiEndpoints.DatabasesApiUrls.Query(databaseId),
body,
queryParams,
cancellationToken: cancellationToken
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Notion.Client
{
// ReSharper disable once ClassNeverInstantiated.Global
public class DatabaseQueryResponse : PaginatedList<IWikiDatabase>
{
}
}
2 changes: 1 addition & 1 deletion Src/Notion.Client/Models/Database/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Notion.Client
{
public class Database : IObject, IObjectModificationData
public class Database : IObject, IObjectModificationData, IWikiDatabase
{
[JsonProperty("title")]
public List<RichTextBase> Title { get; set; }
Expand Down
12 changes: 12 additions & 0 deletions Src/Notion.Client/Models/Database/IWikiDatabase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using JsonSubTypes;
using Newtonsoft.Json;

namespace Notion.Client
{
[JsonConverter(typeof(JsonSubtypes), "object")]
[JsonSubtypes.KnownSubTypeAttribute(typeof(Page), ObjectType.Page)]
[JsonSubtypes.KnownSubTypeAttribute(typeof(Database), ObjectType.Database)]
public interface IWikiDatabase : IObject
{
}
}
2 changes: 1 addition & 1 deletion Src/Notion.Client/Models/Page/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Notion.Client
{
public class Page : IObject, IObjectModificationData
public class Page : IObject, IObjectModificationData, IWikiDatabase
{
/// <summary>
/// The parent of this page. Can be a database, page, or workspace.
Expand Down
85 changes: 85 additions & 0 deletions Test/Notion.IntegrationTests/DatabasesClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Notion.Client;
using Xunit;

namespace Notion.IntegrationTests;

public class DatabasesClientTests : IntegrationTestBase, IDisposable
{
private readonly Page _page;

public DatabasesClientTests()
{
_page = Client.Pages.CreateAsync(
PagesCreateParametersBuilder.Create(
new ParentPageInput { PageId = ParentPageId }
).Build()
).Result;
}

public void Dispose()
{
Client.Pages.UpdateAsync(_page.Id, new PagesUpdateParameters { Archived = true }).Wait();
}

[Fact]
public async Task QueryDatabase()
{
// Arrange
var createdDatabase = await CreateDatabaseWithAPageAsync();

// Act
var response = await Client.Databases.QueryAsync(createdDatabase.Id, new DatabasesQueryParameters());

// Assert
Assert.NotNull(response.Results);
Assert.Single(response.Results);
var page = response.Results.Cast<Page>().First();
var title = page.Properties["Name"] as TitlePropertyValue;
Assert.Equal("Test Title", (title!.Title.Cast<RichTextText>().First()).Text.Content);
}

private async Task<Database> CreateDatabaseWithAPageAsync()
{
var createDbRequest = new DatabasesCreateParameters
{
Title = new List<RichTextBaseInput>
{
new RichTextTextInput
{
Text = new Text
{
Content = "Test List",
Link = null
}
}
},
Properties = new Dictionary<string, IPropertySchema>
{
{ "Name", new TitlePropertySchema { Title = new Dictionary<string, object>() } },
},
Parent = new ParentPageInput { PageId = _page.Id }
};

var createdDatabase = await Client.Databases.CreateAsync(createDbRequest);

var pagesCreateParameters = PagesCreateParametersBuilder
.Create(new DatabaseParentInput { DatabaseId = createdDatabase.Id })
.AddProperty("Name",
new TitlePropertyValue
{
Title = new List<RichTextBase>
{
new RichTextText { Text = new Text { Content = "Test Title" } }
}
})
.Build();

await Client.Pages.CreateAsync(pagesCreateParameters);

return createdDatabase;
}
}
6 changes: 4 additions & 2 deletions Test/Notion.UnitTests/DatabasesClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ public async Task QueryAsync()

pagesPaginatedList.Results.Should().ContainSingle();

foreach (var page in pagesPaginatedList.Results)
foreach (var iWikiDatabase in pagesPaginatedList.Results)
{
var page = (Page)iWikiDatabase;
page.Parent.Should().BeAssignableTo<IPageParent>();
page.Object.Should().Be(ObjectType.Page);
}
Expand Down Expand Up @@ -476,8 +477,9 @@ var jsonData

pagesPaginatedList.Results.Should().ContainSingle();

foreach (var page in pagesPaginatedList.Results)
foreach (var iWikiDatabase in pagesPaginatedList.Results)
{
var page = (Page)iWikiDatabase;
page.Parent.Should().BeAssignableTo<IPageParent>();
page.Object.Should().Be(ObjectType.Page);

Expand Down

0 comments on commit b422493

Please sign in to comment.