anysql 0.3.0 copy "anysql: ^0.3.0" to clipboard
anysql: ^0.3.0 copied to clipboard

A Firebase-style keyword API, setup generator, HTTP backend client, and driver layer for SQL and NoSQL databases.

example/main.dart

import 'package:anysql/anysql.dart';

Future<void> main() async {
  print('anysql example');
  print('-------------');

  final options = AnySqlOptions(
    config: AnySqlConfig.postgres(
      host: 'localhost',
      database: 'app',
      username: 'postgres',
      password: const String.fromEnvironment('ANYSQL_PASSWORD'),
    ),
    backendUri: Uri.parse('https://api.example.com/anysql'),
    backendHeaders: const {'x-client': 'anysql-example'},
  );

  await runDirectAnySqlExample(options);
  await runBackendAnySqlExample(options);
  await runKeywordStoreExample();
}

Future<void> runDirectAnySqlExample(AnySqlOptions options) async {
  print('\n1. Direct driver pattern for trusted Dart code');

  final connection = await options.connect(driver: ExamplePostgresDriver());

  try {
    final result = await connection.query(
      'select id, email from users where id = @id',
      parameters: AnySqlParameters.named({'id': 1}),
    );

    print(result.firstOrNull);
  } finally {
    await connection.close();
  }
}

Future<void> runBackendAnySqlExample(AnySqlOptions options) async {
  print('\n2. Backend/proxy pattern for Flutter mobile apps');

  final connection = await options.connectBackend(
    client: ExampleBackendClient(),
  );

  try {
    final result = await connection.query(
      'users.findById',
      parameters: AnySqlParameters.document({'id': 1}),
    );

    print(result.firstOrNull);
  } finally {
    await connection.close();
  }
}

Future<void> runKeywordStoreExample() async {
  print('\n3. Keyword store pattern over any connection');

  final connection = _ExampleConnection(source: 'keyword store connection');

  try {
    final db = connection.store(dialect: AnySqlDialect.postgres);

    final result = await db
        .collection('users')
        .where('active', isEqualTo: true)
        .limit(10)
        .get();
    print(result.firstOrNull);
  } finally {
    await connection.close();
  }
}

final class ExamplePostgresDriver extends AnySqlDriverBase {
  ExamplePostgresDriver() : super('example_postgres', AnySqlDialect.postgres);

  @override
  Future<AnySqlConnection> connect(AnySqlConfig config) async {
    checkSupported(config);

    return _ExampleConnection(source: 'direct ${config.dialect.name} driver');
  }
}

final class ExampleBackendClient implements AnySqlBackendClient {
  @override
  Future<AnySqlConnection> connect(AnySqlOptions options) async {
    if (!options.hasBackend) {
      throw const AnySqlException('Backend URL is required.');
    }

    return _ExampleConnection(source: 'backend proxy at ${options.backendUri}');
  }
}

final class _ExampleConnection implements AnySqlConnection {
  _ExampleConnection({required this.source});

  final String source;
  var _isOpen = true;

  @override
  bool get isOpen => _isOpen;

  @override
  Future<void> close() async {
    _isOpen = false;
  }

  @override
  Future<AnySqlResult> query(
    String statement, {
    Map<String, Object?> parameters = const {},
  }) async {
    if (!_isOpen) {
      throw const AnySqlException('Connection is closed.');
    }

    return AnySqlResult.rows([
      {'source': source, 'statement': statement, 'parameters': parameters},
    ]);
  }

  @override
  Future<T> transaction<T>(
    Future<T> Function(AnySqlTransaction transaction) action,
  ) async {
    if (!_isOpen) {
      throw const AnySqlException('Connection is closed.');
    }

    final transaction = _ExampleTransaction(this);

    try {
      final value = await action(transaction);
      if (!transaction.isCompleted) {
        await transaction.commit();
      }
      return value;
    } catch (_) {
      if (!transaction.isCompleted) {
        await transaction.rollback();
      }
      rethrow;
    }
  }
}

final class _ExampleTransaction implements AnySqlTransaction {
  _ExampleTransaction(this._connection);

  final _ExampleConnection _connection;
  var isCompleted = false;

  @override
  Future<void> commit() async {
    _checkActive();
    isCompleted = true;
  }

  @override
  Future<AnySqlResult> query(
    String statement, {
    Map<String, Object?> parameters = const {},
  }) {
    _checkActive();
    return _connection.query(statement, parameters: parameters);
  }

  @override
  Future<void> rollback() async {
    _checkActive();
    isCompleted = true;
  }

  void _checkActive() {
    if (isCompleted) {
      throw const AnySqlException('Transaction is already completed.');
    }
  }
}
0
likes
160
points
262
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Firebase-style keyword API, setup generator, HTTP backend client, and driver layer for SQL and NoSQL databases.

Repository (GitHub)
View/report issues

Topics

#database #sql #nosql #cli #configuration

License

MIT (license)

Dependencies

http, mongo_dart, mysql_client, postgres, sqlite3

More

Packages that depend on anysql