Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rearranged query creation for ApiRequest, added FoldedApiRequest wrapper to fold ApiReply with entity conversion #15

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/src/api_client/address/api_address.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class ApiAddress {
_host = host,
_port = port;
///
ApiAddress.localhost({
const ApiAddress.localhost({
int port = 8899,
}) :
_host = '127.0.0.1',
Expand Down
4 changes: 1 addition & 3 deletions lib/src/api_client/query/api_query_type.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
abstract class ApiQueryType {
bool valid();
///
String buildJson();
///
String get authToken;
Map<String, dynamic> buildJson();
///
String get id;
}
26 changes: 4 additions & 22 deletions lib/src/api_client/query/executable_query.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
import 'dart:convert';

import 'package:ext_rw/src/api_client/query/api_query_type.dart';
import 'package:uuid/uuid.dart';

class ExecutableQuery implements ApiQueryType {
final String _authToken;
late String _id;
final String _script;
final Map<String, dynamic> _params;
final bool _keepAlive;
final bool _debug;
///
/// Prapares query for some executable
ExecutableQuery({
required String authToken,
required String script,
required Map<String, dynamic> params,
bool keepAlive = false,
bool debug = false,
}) :
_authToken = authToken,
_script = script,
_params = params,
_keepAlive = keepAlive,
_debug = debug;
_params = params;
///
@override
bool valid() {
Expand All @@ -32,25 +21,18 @@ class ExecutableQuery implements ApiQueryType {
}
///
@override
String buildJson() {
Map<String, dynamic> buildJson() {
_id = const Uuid().v1();
final jsonString = json.encode({
'authToken': _authToken,
return {
'id': _id,
'keepAlive': _keepAlive,
'debug': _debug,
'executable': {
'script': _script,
'params': _params,
},
});
return jsonString;
};
}
///
@override
String get authToken => _authToken;
///
@override
String get id => _id;
///
String get script => _script;
Expand Down
26 changes: 4 additions & 22 deletions lib/src/api_client/query/python_query.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
import 'dart:convert';

import 'package:ext_rw/src/api_client/query/api_query_type.dart';
import 'package:uuid/uuid.dart';

class PythonQuery implements ApiQueryType {
final String _authToken;
late String _id;
final String _script;
final bool _keepAlive;
final bool _debug;
final Map<String, dynamic> _params;
///
/// Prapares query for some python script
PythonQuery({
required String authToken,
required String script,
required Map<String, dynamic> params,
bool keepAlive = false,
bool debug = false,
}) :
_authToken = authToken,
_script = script,
_params = params,
_keepAlive = keepAlive,
_debug = debug;
_params = params;
///
@override
bool valid() {
Expand All @@ -32,25 +21,18 @@ class PythonQuery implements ApiQueryType {
}
///
@override
String buildJson() {
Map<String,dynamic> buildJson() {
_id = const Uuid().v1();
final jsonString = json.encode({
'authToken': _authToken,
return {
'id': _id,
'keepAlive': _keepAlive,
'debug': _debug,
'python': {
'script': _script,
'params': _params,
},
});
return jsonString;
};
}
///
@override
String get authToken => _authToken;
///
@override
String get id => _id;
///
String get script => _script;
Expand Down
26 changes: 4 additions & 22 deletions lib/src/api_client/query/sql_query.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
import 'dart:convert';

import 'package:ext_rw/src/api_client/query/api_query_type.dart';
import 'package:uuid/uuid.dart';

class SqlQuery implements ApiQueryType {
final String _authToken;
late String _id;
final String _database;
final String _sql;
final bool _keepAlive;
final bool _debug;
///
/// Prapares sql for some database
SqlQuery({
required String authToken,
required String database,
required String sql,
bool keepAlive = false,
bool debug = false,
}) :
_authToken = authToken,
_database = database,
_sql = sql,
_keepAlive = keepAlive,
_debug = debug;
_sql = sql;
///
@override
bool valid() {
Expand All @@ -32,25 +21,18 @@ class SqlQuery implements ApiQueryType {
}
///
@override
String buildJson() {
Map<String,dynamic> buildJson() {
_id = const Uuid().v1();
final jsonString = json.encode({
'authToken': _authToken,
return {
'id': _id,
'keepAlive': _keepAlive,
'debug': _debug,
'sql': {
'database': _database,
'sql': _sql,
},
});
return jsonString;
};
}
///
@override
String get authToken => _authToken;
///
@override
String get id => _id;
///
String get database => _database;
Expand Down
30 changes: 21 additions & 9 deletions lib/src/api_client/request/api_request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,32 @@ import 'package:hmi_core/hmi_core_result_new.dart';
class ApiRequest {
static final _log = const Log('ApiRequest')..level = LogLevel.info;
final ApiAddress _address;
final ApiQueryType _query;
final String _authToken;
final bool _debug;
final bool _keepAlive;
///
ApiRequest({
const ApiRequest({
required ApiAddress address,
required ApiQueryType query,
required String authToken,
bool debug = false,
bool keepAlive = false,
}) :
_debug = debug,
_keepAlive = keepAlive,
_address = address,
_query = query;
_authToken = authToken;
///
/// sends created request to the remote
/// returns reply if exists
Future<Result<ApiReply, Failure>> fetch() async {
final query = _query.buildJson();
final bytes = utf8.encode(query);
/// Sends [query] to the remote.
/// Returns reply if exists.
Future<Result<ApiReply, Failure>> fetch(ApiQueryType query) async {
final queryWithHeaders = {
'authToken': _authToken,
'debug': _debug,
'keepAlive': _keepAlive,
...query.buildJson(),
};
final jsonString = json.encode(queryWithHeaders);
final bytes = utf8.encode(jsonString);
if (kIsWeb) {
return _fetchWebSocket(bytes);
} else {
Expand Down
6 changes: 6 additions & 0 deletions lib/src/api_client/request/converted.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:hmi_core/hmi_core_result_new.dart';
///
abstract interface class Converted<I, O> {
///
ResultF<O> valueFrom(I input);
}
45 changes: 45 additions & 0 deletions lib/src/api_client/request/folded_api_request.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:ext_rw/src/api_client/query/api_query_type.dart';
import 'package:ext_rw/src/api_client/request/api_request.dart';
import 'package:hmi_core/hmi_core_failure.dart';
import 'package:hmi_core/hmi_core_log.dart';
import 'package:hmi_core/hmi_core_result_new.dart';
import 'converted.dart';
///
final class FoldedApiRequest<T> {
static final _log = const Log('FoldedApiRequest')..level = LogLevel.info;
final ApiRequest _request;
final Converted<Map<String,dynamic>, T> _converted;
///
/// Converts maps from [request]'s reply into entities using [converted].
const FoldedApiRequest({
required ApiRequest request,
required Converted<Map<String,dynamic>, T> converted,
}) :
_request = request,
_converted = converted;
///
/// Sends [query] to the remote.
/// Returns entities if exist.
Future<ResultF<List<T>>> fetch(ApiQueryType query) async {
return _request.fetch(query)
.then((replyResult) => switch(replyResult) {
Ok(value:final reply) => _parse(reply.data),
Err(:final error) => Err(error),
});
}
///
/// Parse [entries] with [_converted].
ResultF<List<T>> _parse(List<Map<String, dynamic>> entries) {
final parsedEntries = <T>[];
for(final entry in entries) {
switch(_converted.valueFrom(entry)) {
case Ok<T, Failure>(:final value):
parsedEntries.add(value);
case Err<T, Failure>(:final error):
_log.warning('Error while converting $entry to $T');
return Err(error);
}
}
return Ok(parsedEntries);
}
}
33 changes: 7 additions & 26 deletions lib/src/table_schema/schema.dart
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
import 'package:ext_rw/ext_rw.dart';
import 'package:ext_rw/src/sql/sql.dart';
import 'package:ext_rw/src/table_schema/field.dart';
import 'package:ext_rw/src/table_schema/schema_entry.dart';
import 'package:hmi_core/hmi_core_failure.dart';
import 'package:hmi_core/hmi_core_log.dart';
import 'package:hmi_core/hmi_core_result_new.dart';

typedef SqlBuilder<T extends SchemaEntry> = Sql Function(Sql sql, T entry);


///
/// A collection of the SchameEntry,
/// abstruction on the SQL table rows
class Schema<T extends SchemaEntry> {
late final Log _log;
final ApiAddress _address;
final String _authToken;
final ApiRequest _request;
final String _database;
final bool _keepAlive;
final bool _debug;
final List<Field> _fields;
final Map<String, T> _entries = {};
final Sql Function(List<dynamic>? values) _fetchSqlBuilder;
Expand All @@ -33,25 +26,19 @@ class Schema<T extends SchemaEntry> {
/// abstruction on the SQL table rows
/// - [keys] - list of table field names
Schema({
required ApiAddress address,
required String authToken,
required ApiRequest request,
required String database,
required List<Field> fields,
bool keepAlive = false,
bool debug = false,
required Sql Function(List<dynamic>? values) fetchSqlBuilder,
SqlBuilder<T>? insertSqlBuilder,
SqlBuilder<T>? updateSqlBuilder,
Map<String, Schema> relations = const {},
required Map<T, Function> entryFromFactories,
required Map<T, Function> entryEmptyFactories,
}) :
_address = address,
_authToken = authToken,
_request = request,
_database = database,
_fields = fields,
_keepAlive = keepAlive,
_debug = debug,
_fetchSqlBuilder = fetchSqlBuilder,
_insertSqlBuilder = insertSqlBuilder,
_updateSqlBuilder = updateSqlBuilder,
Expand Down Expand Up @@ -115,17 +102,11 @@ class Schema<T extends SchemaEntry> {
///
/// Fetchs data with new [sql]
Future<Result<List<T>, Failure>> fetchWith(Sql sql) {
final request = ApiRequest(
address: _address,
query: SqlQuery(
authToken: _authToken,
database: _database,
sql: sql.build(),
keepAlive: _keepAlive,
debug: _debug,
),
final query = SqlQuery(
database: _database,
sql: sql.build(),
);
return request.fetch().then((result) {
return _request.fetch(query).then((result) {
return switch (result) {
Ok(:final value) => () {
final reply = value;
Expand Down