Skip to content

Commit a03d213

Browse files
authored
Merge pull request #31 from getditto/CX-539_Query_Editor
CX-539: Simple Query Editor with option to share results with existing Share API implementation
2 parents 432f910 + f428ef7 commit a03d213

File tree

9 files changed

+633
-3
lines changed

9 files changed

+633
-3
lines changed

README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,84 @@ In the second scenario, you can be quite confident that your data is still the m
347347
That said, the aim of this tool is to provide heuristics that you can combine with an understanding of your data model to get an accurate picture of the state of your device.
348348
If you have specific knowledge about your data model or update frequency, you can use that knowledge to get a clearer view of the data you have locally.
349349

350+
## `QueryEditorView`
351+
352+
The `QueryEditorView` provides an interactive interface for executing DQL (Ditto Query Language) statements against your Ditto database. This tool helps developers test queries, inspect data, and perform CRUD operations during development and debugging, with built-in export functionality for query results.
353+
354+
### Usage
355+
356+
The `QueryEditorView` can be used as a standalone widget in your Flutter application:
357+
358+
```dart
359+
import 'package:ditto_flutter_tools/ditto_flutter_tools.dart';
360+
361+
// In your widget build method
362+
Scaffold(
363+
appBar: AppBar(title: Text('Query Editor')),
364+
body: QueryEditorView(ditto: myDittoInstance),
365+
)
366+
```
367+
368+
Or navigate to it from your debug menu:
369+
370+
```dart
371+
Navigator.push(
372+
context,
373+
MaterialPageRoute(
374+
builder: (context) => QueryEditorView(ditto: ditto),
375+
),
376+
);
377+
```
378+
379+
### Features
380+
381+
The query editor provides:
382+
383+
1. **Multi-line Query Input** - A text field for entering DQL statements with syntax hints
384+
2. **Async Query Execution** - Non-blocking query execution with loading indicator
385+
3. **Paginated Results Display** - Large result sets with configurable pagination (10, 25, 50, 100 items per page)
386+
4. **Export Functionality** - Share query results as JSON files using the native Share API
387+
5. **Error Handling** - Clear error messages for invalid queries or execution failures
388+
6. **Multiple Query Types** - Supports SELECT, INSERT, UPDATE, and DELETE operations
389+
390+
### Export Functionality
391+
392+
The query editor includes built-in export capabilities:
393+
394+
#### Share Results
395+
- **Smart Export**: Share button only appears when query results contain actual data (not status messages)
396+
- **JSON Format**: Results are exported as raw JSON data without formatting or metadata
397+
- **Automatic Cleanup**: Temporary files are automatically cleaned up after sharing
398+
399+
#### Export Features
400+
- **JSON Files**: Query results are exported with `.json` extension and proper MIME type
401+
- **Raw Data Only**: Exports only the actual query result data, no headers or formatting
402+
403+
### Query Results & Pagination
404+
405+
The view handles multiple result types with advanced pagination:
406+
407+
1. **Query Results (SELECT)**:
408+
- Each document displayed as a separate item
409+
- Configurable pagination (10, 25, 50, 100 items per page)
410+
- Page navigation controls with direct page input
411+
- Results counter showing total items and current page range
412+
- Export functionality available for data results
413+
414+
2. **Mutation Results (INSERT/UPDATE/DELETE)**:
415+
- List of affected document IDs
416+
- Number of documents modified
417+
- Transaction/commit ID when available
418+
- No export functionality (status messages only)
419+
420+
### DQL Documentation
421+
422+
For comprehensive DQL syntax and examples, refer to the official Ditto documentation:
423+
- [Read Operations](https://docs.ditto.live/sdk/latest/crud/read)
424+
- [Create Operations](https://docs.ditto.live/sdk/latest/crud/create)
425+
- [Update Operations](https://docs.ditto.live/sdk/latest/crud/update)
426+
- [Delete Operations](https://docs.ditto.live/sdk/latest/crud/delete)
427+
350428

351429
## `PermissionsHealthView`
352430

@@ -506,6 +584,8 @@ This package uses the following third-party libraries:
506584
- **Repository**: https://pub.dev/packages/share_plus
507585
- **Note**: Used for all export functionality (logs and database) to provide a consistent, native sharing experience across iOS, Android, macOS, and Linux platforms.
508586

587+
588+
509589
## Support
510590

511591
For support, please contact Ditto Support (<[email protected]>).

example/lib/constants/routes.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ const String peerSyncStatusRoute = '/peer-sync-status';
66
const String permissionsHealthRoute = '/permissions-health';
77
const String diskUsageRoute = '/disk-usage';
88
const String systemSettingsRoute = '/system-settings';
9+
const String queryEditorRoute = '/query-editor';

example/lib/main.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'screens/peer_sync_status_screen.dart';
1313
import 'screens/permissions_health_screen.dart';
1414
import 'screens/disk_usage_screen.dart';
1515
import 'screens/system_settings_screen.dart';
16+
import 'screens/query_editor_screen.dart';
1617
import 'constants/routes.dart';
1718

1819
Future<void> main() async {
@@ -129,6 +130,9 @@ class _DittoExampleState extends State<DittoExample> {
129130
systemSettingsRoute: (context, state, data) => SystemSettingsScreen(
130131
ditto: dittoService.ditto,
131132
),
133+
queryEditorRoute: (context, state, data) => QueryEditorScreen(
134+
ditto: dittoService.ditto,
135+
),
132136
},
133137
),
134138
);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import 'package:ditto_flutter_tools/ditto_flutter_tools.dart';
2+
import 'package:flutter/material.dart';
3+
import 'package:ditto_live/ditto_live.dart';
4+
5+
class QueryEditorScreen extends StatelessWidget {
6+
final Ditto ditto;
7+
8+
const QueryEditorScreen({
9+
super.key,
10+
required this.ditto,
11+
});
12+
13+
@override
14+
Widget build(BuildContext context) {
15+
return Scaffold(
16+
appBar: AppBar(title: const Text("Query Editor")),
17+
body: QueryEditorView(
18+
ditto: ditto,
19+
),
20+
);
21+
}
22+
}

example/lib/widgets/main_list_view.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,60 @@ class MainListView extends StatelessWidget {
115115
],
116116
),
117117
),
118+
119+
const SizedBox(height: 20),
120+
// DITTO Store Section
121+
Padding(
122+
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
123+
child: Text(
124+
"DITTO STORE",
125+
style: TextStyle(
126+
fontSize: 13,
127+
fontWeight: FontWeight.w600,
128+
color: Theme.of(context)
129+
.textTheme
130+
.labelLarge
131+
?.color
132+
?.withOpacity(0.6),
133+
letterSpacing: 0.5,
134+
),
135+
),
136+
),
137+
Container(
138+
margin: const EdgeInsets.symmetric(horizontal: 16),
139+
decoration: BoxDecoration(
140+
color: Theme.of(context).colorScheme.surface,
141+
borderRadius: BorderRadius.circular(10),
142+
border: Border.all(
143+
color:
144+
Theme.of(context).colorScheme.outline.withOpacity(0.3)),
145+
),
146+
child: Column(
147+
children: [
148+
ListTile(
149+
leading: Container(
150+
width: 32,
151+
height: 32,
152+
decoration: BoxDecoration(
153+
color: Colors.lightBlue,
154+
borderRadius: BorderRadius.circular(8),
155+
),
156+
child: const Icon(
157+
Icons.code,
158+
color: Colors.white,
159+
size: 20,
160+
),
161+
),
162+
title: const Text("Query Editor"),
163+
trailing: Icon(Icons.chevron_right,
164+
color: Theme.of(context).colorScheme.onSurfaceVariant),
165+
onTap: () =>
166+
Beamer.of(context).beamToNamed(queryEditorRoute),
167+
),
168+
],
169+
),
170+
),
171+
118172
const SizedBox(height: 20),
119173
// SYSTEM Section
120174
Padding(

example/pubspec.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,10 @@ packages:
338338
dependency: transitive
339339
description:
340340
name: intl
341-
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
341+
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
342342
url: "https://pub.dev"
343343
source: hosted
344-
version: "0.19.0"
344+
version: "0.18.1"
345345
json_annotation:
346346
dependency: "direct main"
347347
description:

lib/ditto_flutter_tools.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ export "src/permissions_health/wifi_permissions_cross_platform.dart"
1313
export "src/sync_status_view.dart" show SyncStatusView;
1414
export "src/sync_status_helper.dart" show SyncStatusHelper, SyncStatus;
1515
export "src/peer_list.dart" show PeerListView;
16-
export "src/system_settings_view.dart" show SystemSettingsView;
1716
export "src/peer_sync_status/peer_sync_status_view.dart" show PeerSyncStatusView;
17+
export "src/system_settings_view.dart" show SystemSettingsView;
18+
export "src/query_editor/query_editor_view.dart" show QueryEditorView;

0 commit comments

Comments
 (0)