88 */
99
1010using System ;
11+ using System . IO ;
12+ using System . IO . Compression ;
13+ using System . Linq ;
1114using System . Net ;
1215using System . Threading . Tasks ;
1316using Amazon . DynamoDBv2 ;
1417using GuiStack . Extensions ;
1518using GuiStack . Models ;
1619using GuiStack . Repositories ;
1720using Microsoft . AspNetCore . Mvc ;
21+ using Microsoft . AspNetCore . WebUtilities ;
22+ using Newtonsoft . Json ;
1823
1924namespace GuiStack . Controllers . DynamoDB
2025{
@@ -29,6 +34,40 @@ public TablesController(IDynamoDBRepository dynamodbRepository)
2934 this . dynamodbRepository = dynamodbRepository ;
3035 }
3136
37+ private static DynamoDBItemModel DeserializeItem ( string data )
38+ {
39+ using var resultStream = new MemoryStream ( ) ;
40+ using var reader = new StreamReader ( resultStream ) ;
41+
42+ using ( var compressedStream = new MemoryStream ( WebEncoders . Base64UrlDecode ( data ) ) )
43+ using ( var decompressionStream = new GZipStream ( compressedStream , CompressionMode . Decompress ) )
44+ {
45+ decompressionStream . CopyTo ( resultStream ) ;
46+ }
47+
48+ resultStream . Position = 0 ;
49+
50+ var json = reader . ReadToEnd ( ) ;
51+
52+ // Utilizing Newtonsoft.Json as it better handles scalar types (string, int, etc.) when the target property is of type System.Object
53+ // System.Text.Json deserializes these as JsonElement, which is not ideal
54+ return JsonConvert . DeserializeObject < DynamoDBItemModel > ( json ) ;
55+ }
56+
57+ private static string SerializeItem ( DynamoDBItemModel model )
58+ {
59+ using var stream = new MemoryStream ( ) ;
60+
61+ using ( var compressionStream = new GZipStream ( stream , CompressionLevel . Fastest ) )
62+ using ( var writer = new StreamWriter ( compressionStream ) )
63+ {
64+ var json = JsonConvert . SerializeObject ( model ) ;
65+ writer . Write ( json ) ;
66+ }
67+
68+ return WebEncoders . Base64UrlEncode ( stream . ToArray ( ) ) ;
69+ }
70+
3271 private ActionResult HandleException ( Exception ex )
3372 {
3473 if ( ex == null )
@@ -85,6 +124,51 @@ public async Task<ActionResult> DeleteTable([FromRoute] string tableName)
85124 }
86125 }
87126
127+ [ HttpGet ( "{tableName}" ) ]
128+ [ Produces ( "application/json" ) ]
129+ public async Task < ActionResult > GetItems ( [ FromRoute ] string tableName , [ FromQuery ] int limit = 50 , [ FromQuery ( Name = "lastEvaluatedKey" ) ] string lastKey = null )
130+ {
131+ if ( string . IsNullOrWhiteSpace ( tableName ) || limit < 1 || limit > 500 )
132+ return StatusCode ( ( int ) HttpStatusCode . BadRequest ) ;
133+
134+ tableName = tableName . DecodeRouteParameter ( ) ;
135+
136+ try
137+ {
138+ var lastKeyItem = ! string . IsNullOrWhiteSpace ( lastKey )
139+ ? DeserializeItem ( lastKey )
140+ : null ;
141+
142+ var table = await dynamodbRepository . GetTableInfoAsync ( tableName ) ;
143+ var result = await dynamodbRepository . ScanAsync ( tableName , limit , lastKeyItem ) ;
144+
145+ var lastEvaluatedKey = result . LastEvaluatedKey != null
146+ ? SerializeItem ( result . LastEvaluatedKey )
147+ : null ;
148+
149+ var attributeNames = new [ ] { table . PartitionKey . Name , table . SortKey ? . Name } // Ensure PartitionKey and SortKey are always first
150+ . Where ( name => name != null )
151+ . Concat ( result . Items // Join with the rest of the fields
152+ . SelectMany ( item => item . Select ( kvp => kvp . Key ) )
153+ . Where ( name => name != table . PartitionKey . Name && ( table . SortKey == null || name != table . SortKey . Name ) )
154+ . Distinct ( )
155+ )
156+ . ToArray ( ) ;
157+
158+ return Json ( new DynamoDBTableContentsModel ( ) {
159+ PartitionKey = table . PartitionKey ,
160+ SortKey = table . SortKey ,
161+ AttributeNames = attributeNames ,
162+ LastEvaluatedKey = lastEvaluatedKey ,
163+ Items = result . Items
164+ } ) ;
165+ }
166+ catch ( Exception ex )
167+ {
168+ return HandleException ( ex ) ;
169+ }
170+ }
171+
88172 [ HttpPut ( "{tableName}" ) ]
89173 [ Consumes ( "application/json" ) ]
90174 public async Task < ActionResult > PutItem ( [ FromRoute ] string tableName , [ FromBody ] DynamoDBItemModel model )
0 commit comments