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

Updated the postgres package to version 3.0.0 #71

Merged
merged 2 commits into from
Feb 5, 2024
Merged
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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
- You no longer need to use the `Database` class, you can use `Connection.open` or `Pool` directly.
- `Database` class implements postegres `Session` and `SessionExecutor` classes
- Extension methods for accessing repositories now extend `Session`
- Added the ability to create a Pool for your database
- Updated analyzer dependency to `^6.0.0`
- Updated dart sdk constraints to `>=2.17.0 <4.0.0`

**BREAKING CHANGES**
- Updated the `postgres` package to version `3.0.0`. To visit all the breaking changes see their changelog
- Removed `Database.query` method in favour of `Session.execute` method
- `Action` and `Query` now accept a Session
- Repository methods are no longer wrapped in a transaction
- Removed all fields and methods to execute a transaction in favor of `SessionExecutor.runTx`

# 0.13.1

- Fixed bug with boolean column in migration.
Expand Down
2 changes: 1 addition & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Future<void> main() async {
var db = Database(
port: 2222,
database: 'dart_test',
user: 'postgres',
username: 'postgres',
password: 'postgres',
useSSL: false,
);
Expand Down
28 changes: 14 additions & 14 deletions example/lib/models/account.schema.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

part of 'account.dart';

extension AccountRepositories on Database {
extension AccountRepositories on Session {
AccountRepository get accounts => AccountRepository._(this);
}

Expand All @@ -12,7 +12,7 @@ abstract class AccountRepository
KeyedModelRepositoryInsert<AccountInsertRequest>,
ModelRepositoryUpdate<AccountUpdateRequest>,
ModelRepositoryDelete<int> {
factory AccountRepository._(Database db) = _AccountRepository;
factory AccountRepository._(Session db) = _AccountRepository;

Future<FullAccountView?> queryFullView(int id);
Future<List<FullAccountView>> queryFullViews([QueryParams? params]);
Expand Down Expand Up @@ -64,11 +64,11 @@ class _AccountRepository extends BaseRepository
Future<List<int>> insert(List<AccountInsertRequest> requests) async {
if (requests.isEmpty) return [];
var values = QueryValues();
var rows = await db.query(
'INSERT INTO "accounts" ( "first_name", "last_name", "location", "company_id" )\n'
'VALUES ${requests.map((r) => '( ${values.add(r.firstName)}:text, ${values.add(r.lastName)}:text, ${values.add(LatLngConverter().tryEncode(r.location))}:point, ${values.add(r.companyId)}:text )').join(', ')}\n'
'RETURNING "id"',
values.values,
var rows = await db.execute(
Sql.named('INSERT INTO "accounts" ( "first_name", "last_name", "location", "company_id" )\n'
'VALUES ${requests.map((r) => '( ${values.add(r.firstName)}:text, ${values.add(r.lastName)}:text, ${values.add(LatLngConverter().tryEncode(r.location))}:point, ${values.add(r.companyId)}:text )').join(', ')}\n'
'RETURNING "id"'),
parameters: values.values,
);
var result = rows.map<int>((r) => TextEncoder.i.decode(r.toColumnMap()['id'])).toList();

Expand All @@ -89,13 +89,13 @@ class _AccountRepository extends BaseRepository
Future<void> update(List<AccountUpdateRequest> requests) async {
if (requests.isEmpty) return;
var values = QueryValues();
await db.query(
'UPDATE "accounts"\n'
'SET "first_name" = COALESCE(UPDATED."first_name", "accounts"."first_name"), "last_name" = COALESCE(UPDATED."last_name", "accounts"."last_name"), "location" = COALESCE(UPDATED."location", "accounts"."location"), "company_id" = COALESCE(UPDATED."company_id", "accounts"."company_id")\n'
'FROM ( VALUES ${requests.map((r) => '( ${values.add(r.id)}:int8, ${values.add(r.firstName)}:text, ${values.add(r.lastName)}:text, ${values.add(LatLngConverter().tryEncode(r.location))}:point, ${values.add(r.companyId)}:text )').join(', ')} )\n'
'AS UPDATED("id", "first_name", "last_name", "location", "company_id")\n'
'WHERE "accounts"."id" = UPDATED."id"',
values.values,
await db.execute(
Sql.named('UPDATE "accounts"\n'
'SET "first_name" = COALESCE(UPDATED."first_name", "accounts"."first_name"), "last_name" = COALESCE(UPDATED."last_name", "accounts"."last_name"), "location" = COALESCE(UPDATED."location", "accounts"."location"), "company_id" = COALESCE(UPDATED."company_id", "accounts"."company_id")\n'
'FROM ( VALUES ${requests.map((r) => '( ${values.add(r.id)}:int8::int8, ${values.add(r.firstName)}:text::text, ${values.add(r.lastName)}:text::text, ${values.add(LatLngConverter().tryEncode(r.location))}:point::point, ${values.add(r.companyId)}:text::text )').join(', ')} )\n'
'AS UPDATED("id", "first_name", "last_name", "location", "company_id")\n'
'WHERE "accounts"."id" = UPDATED."id"'),
parameters: values.values,
);
await db.billingAddresses.updateMany(requests.where((r) => r.billingAddress != null).map((r) {
return BillingAddressUpdateRequest(
Expand Down
27 changes: 14 additions & 13 deletions example/lib/models/address.schema.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

part of 'address.dart';

extension AddressRepositories on Database {
extension AddressRepositories on Session {
BillingAddressRepository get billingAddresses => BillingAddressRepository._(this);
}

Expand All @@ -11,7 +11,7 @@ abstract class BillingAddressRepository
ModelRepository,
ModelRepositoryInsert<BillingAddressInsertRequest>,
ModelRepositoryUpdate<BillingAddressUpdateRequest> {
factory BillingAddressRepository._(Database db) = _BillingAddressRepository;
factory BillingAddressRepository._(Session db) = _BillingAddressRepository;

Future<List<BillingAddressView>> queryBillingAddresses([QueryParams? params]);
}
Expand All @@ -32,24 +32,25 @@ class _BillingAddressRepository extends BaseRepository
Future<void> insert(List<BillingAddressInsertRequest> requests) async {
if (requests.isEmpty) return;
var values = QueryValues();
await db.query(
'INSERT INTO "billing_addresses" ( "city", "postcode", "name", "street", "account_id", "company_id" )\n'
'VALUES ${requests.map((r) => '( ${values.add(r.city)}:text, ${values.add(r.postcode)}:text, ${values.add(r.name)}:text, ${values.add(r.street)}:text, ${values.add(r.accountId)}:int8, ${values.add(r.companyId)}:text )').join(', ')}\n',
values.values,
await db.execute(
Sql.named(
'INSERT INTO "billing_addresses" ( "city", "postcode", "name", "street", "account_id", "company_id" )\n'
'VALUES ${requests.map((r) => '( ${values.add(r.city)}:text, ${values.add(r.postcode)}:text, ${values.add(r.name)}:text, ${values.add(r.street)}:text, ${values.add(r.accountId)}:int8, ${values.add(r.companyId)}:text )').join(', ')}\n'),
parameters: values.values,
);
}

@override
Future<void> update(List<BillingAddressUpdateRequest> requests) async {
if (requests.isEmpty) return;
var values = QueryValues();
await db.query(
'UPDATE "billing_addresses"\n'
'SET "city" = COALESCE(UPDATED."city", "billing_addresses"."city"), "postcode" = COALESCE(UPDATED."postcode", "billing_addresses"."postcode"), "name" = COALESCE(UPDATED."name", "billing_addresses"."name"), "street" = COALESCE(UPDATED."street", "billing_addresses"."street")\n'
'FROM ( VALUES ${requests.map((r) => '( ${values.add(r.city)}:text, ${values.add(r.postcode)}:text, ${values.add(r.name)}:text, ${values.add(r.street)}:text, ${values.add(r.accountId)}:int8, ${values.add(r.companyId)}:text )').join(', ')} )\n'
'AS UPDATED("city", "postcode", "name", "street", "account_id", "company_id")\n'
'WHERE "billing_addresses"."account_id" = UPDATED."account_id" AND "billing_addresses"."company_id" = UPDATED."company_id"',
values.values,
await db.execute(
Sql.named('UPDATE "billing_addresses"\n'
'SET "city" = COALESCE(UPDATED."city", "billing_addresses"."city"), "postcode" = COALESCE(UPDATED."postcode", "billing_addresses"."postcode"), "name" = COALESCE(UPDATED."name", "billing_addresses"."name"), "street" = COALESCE(UPDATED."street", "billing_addresses"."street")\n'
'FROM ( VALUES ${requests.map((r) => '( ${values.add(r.city)}:text::text, ${values.add(r.postcode)}:text::text, ${values.add(r.name)}:text::text, ${values.add(r.street)}:text::text, ${values.add(r.accountId)}:int8::int8, ${values.add(r.companyId)}:text::text )').join(', ')} )\n'
'AS UPDATED("city", "postcode", "name", "street", "account_id", "company_id")\n'
'WHERE "billing_addresses"."account_id" = UPDATED."account_id" AND "billing_addresses"."company_id" = UPDATED."company_id"'),
parameters: values.values,
);
}
}
Expand Down
26 changes: 13 additions & 13 deletions example/lib/models/company.schema.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

part of 'company.dart';

extension CompanyRepositories on Database {
extension CompanyRepositories on Session {
CompanyRepository get companies => CompanyRepository._(this);
}

Expand All @@ -12,7 +12,7 @@ abstract class CompanyRepository
ModelRepositoryInsert<CompanyInsertRequest>,
ModelRepositoryUpdate<CompanyUpdateRequest>,
ModelRepositoryDelete<String> {
factory CompanyRepository._(Database db) = _CompanyRepository;
factory CompanyRepository._(Session db) = _CompanyRepository;

Future<FullCompanyView?> queryFullView(String id);
Future<List<FullCompanyView>> queryFullViews([QueryParams? params]);
Expand Down Expand Up @@ -52,10 +52,10 @@ class _CompanyRepository extends BaseRepository
Future<void> insert(List<CompanyInsertRequest> requests) async {
if (requests.isEmpty) return;
var values = QueryValues();
await db.query(
'INSERT INTO "companies" ( "id", "name" )\n'
'VALUES ${requests.map((r) => '( ${values.add(r.id)}:text, ${values.add(r.name)}:text )').join(', ')}\n',
values.values,
await db.execute(
Sql.named('INSERT INTO "companies" ( "id", "name" )\n'
'VALUES ${requests.map((r) => '( ${values.add(r.id)}:text, ${values.add(r.name)}:text )').join(', ')}\n'),
parameters: values.values,
);

await db.billingAddresses.insertMany(requests.expand((r) {
Expand All @@ -73,13 +73,13 @@ class _CompanyRepository extends BaseRepository
Future<void> update(List<CompanyUpdateRequest> requests) async {
if (requests.isEmpty) return;
var values = QueryValues();
await db.query(
'UPDATE "companies"\n'
'SET "name" = COALESCE(UPDATED."name", "companies"."name")\n'
'FROM ( VALUES ${requests.map((r) => '( ${values.add(r.id)}:text, ${values.add(r.name)}:text )').join(', ')} )\n'
'AS UPDATED("id", "name")\n'
'WHERE "companies"."id" = UPDATED."id"',
values.values,
await db.execute(
Sql.named('UPDATE "companies"\n'
'SET "name" = COALESCE(UPDATED."name", "companies"."name")\n'
'FROM ( VALUES ${requests.map((r) => '( ${values.add(r.id)}:text::text, ${values.add(r.name)}:text::text )').join(', ')} )\n'
'AS UPDATED("id", "name")\n'
'WHERE "companies"."id" = UPDATED."id"'),
parameters: values.values,
);
await db.billingAddresses.updateMany(requests.where((r) => r.addresses != null).expand((r) {
return r.addresses!.map((rr) => BillingAddressUpdateRequest(
Expand Down
27 changes: 14 additions & 13 deletions example/lib/models/invoice.schema.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

part of 'invoice.dart';

extension InvoiceRepositories on Database {
extension InvoiceRepositories on Session {
InvoiceRepository get invoices => InvoiceRepository._(this);
}

Expand All @@ -12,7 +12,7 @@ abstract class InvoiceRepository
ModelRepositoryInsert<InvoiceInsertRequest>,
ModelRepositoryUpdate<InvoiceUpdateRequest>,
ModelRepositoryDelete<String> {
factory InvoiceRepository._(Database db) = _InvoiceRepository;
factory InvoiceRepository._(Session db) = _InvoiceRepository;

Future<OwnerInvoiceView?> queryOwnerView(String id);
Future<List<OwnerInvoiceView>> queryOwnerViews([QueryParams? params]);
Expand Down Expand Up @@ -40,24 +40,25 @@ class _InvoiceRepository extends BaseRepository
Future<void> insert(List<InvoiceInsertRequest> requests) async {
if (requests.isEmpty) return;
var values = QueryValues();
await db.query(
'INSERT INTO "invoices" ( "id", "title", "invoice_id", "account_id", "company_id" )\n'
'VALUES ${requests.map((r) => '( ${values.add(r.id)}:text, ${values.add(r.title)}:text, ${values.add(r.invoiceId)}:text, ${values.add(r.accountId)}:int8, ${values.add(r.companyId)}:text )').join(', ')}\n',
values.values,
await db.execute(
Sql.named(
'INSERT INTO "invoices" ( "id", "title", "invoice_id", "account_id", "company_id" )\n'
'VALUES ${requests.map((r) => '( ${values.add(r.id)}:text, ${values.add(r.title)}:text, ${values.add(r.invoiceId)}:text, ${values.add(r.accountId)}:int8, ${values.add(r.companyId)}:text )').join(', ')}\n'),
parameters: values.values,
);
}

@override
Future<void> update(List<InvoiceUpdateRequest> requests) async {
if (requests.isEmpty) return;
var values = QueryValues();
await db.query(
'UPDATE "invoices"\n'
'SET "title" = COALESCE(UPDATED."title", "invoices"."title"), "invoice_id" = COALESCE(UPDATED."invoice_id", "invoices"."invoice_id"), "account_id" = COALESCE(UPDATED."account_id", "invoices"."account_id"), "company_id" = COALESCE(UPDATED."company_id", "invoices"."company_id")\n'
'FROM ( VALUES ${requests.map((r) => '( ${values.add(r.id)}:text, ${values.add(r.title)}:text, ${values.add(r.invoiceId)}:text, ${values.add(r.accountId)}:int8, ${values.add(r.companyId)}:text )').join(', ')} )\n'
'AS UPDATED("id", "title", "invoice_id", "account_id", "company_id")\n'
'WHERE "invoices"."id" = UPDATED."id"',
values.values,
await db.execute(
Sql.named('UPDATE "invoices"\n'
'SET "title" = COALESCE(UPDATED."title", "invoices"."title"), "invoice_id" = COALESCE(UPDATED."invoice_id", "invoices"."invoice_id"), "account_id" = COALESCE(UPDATED."account_id", "invoices"."account_id"), "company_id" = COALESCE(UPDATED."company_id", "invoices"."company_id")\n'
'FROM ( VALUES ${requests.map((r) => '( ${values.add(r.id)}:text::text, ${values.add(r.title)}:text::text, ${values.add(r.invoiceId)}:text::text, ${values.add(r.accountId)}:int8::int8, ${values.add(r.companyId)}:text::text )').join(', ')} )\n'
'AS UPDATED("id", "title", "invoice_id", "account_id", "company_id")\n'
'WHERE "invoices"."id" = UPDATED."id"'),
parameters: values.values,
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions example/lib/models/latlng.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ class LatLngConverter extends TypeConverter<LatLng> {
const LatLngConverter() : super('point');

@override
dynamic encode(LatLng value) => PgPoint(value.latitude, value.longitude);
dynamic encode(LatLng value) => Point(value.latitude, value.longitude);

@override
LatLng decode(dynamic value) {
if (value is PgPoint) {
if (value is Point) {
return LatLng(value.latitude, value.longitude);
} else {
var m = RegExp(r'\((.+),(.+)\)').firstMatch(value.toString());
Expand Down
26 changes: 13 additions & 13 deletions example/lib/models/party.schema.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

part of 'party.dart';

extension PartyRepositories on Database {
extension PartyRepositories on Session {
PartyRepository get parties => PartyRepository._(this);
}

Expand All @@ -12,7 +12,7 @@ abstract class PartyRepository
ModelRepositoryInsert<PartyInsertRequest>,
ModelRepositoryUpdate<PartyUpdateRequest>,
ModelRepositoryDelete<String> {
factory PartyRepository._(Database db) = _PartyRepository;
factory PartyRepository._(Session db) = _PartyRepository;

Future<GuestPartyView?> queryGuestView(String id);
Future<List<GuestPartyView>> queryGuestViews([QueryParams? params]);
Expand Down Expand Up @@ -52,24 +52,24 @@ class _PartyRepository extends BaseRepository
Future<void> insert(List<PartyInsertRequest> requests) async {
if (requests.isEmpty) return;
var values = QueryValues();
await db.query(
'INSERT INTO "parties" ( "id", "name", "sponsor_id", "date" )\n'
'VALUES ${requests.map((r) => '( ${values.add(r.id)}:text, ${values.add(r.name)}:text, ${values.add(r.sponsorId)}:text, ${values.add(r.date)}:int8 )').join(', ')}\n',
values.values,
await db.execute(
Sql.named('INSERT INTO "parties" ( "id", "name", "sponsor_id", "date" )\n'
'VALUES ${requests.map((r) => '( ${values.add(r.id)}:text, ${values.add(r.name)}:text, ${values.add(r.sponsorId)}:text, ${values.add(r.date)}:int8 )').join(', ')}\n'),
parameters: values.values,
);
}

@override
Future<void> update(List<PartyUpdateRequest> requests) async {
if (requests.isEmpty) return;
var values = QueryValues();
await db.query(
'UPDATE "parties"\n'
'SET "name" = COALESCE(UPDATED."name", "parties"."name"), "sponsor_id" = COALESCE(UPDATED."sponsor_id", "parties"."sponsor_id"), "date" = COALESCE(UPDATED."date", "parties"."date")\n'
'FROM ( VALUES ${requests.map((r) => '( ${values.add(r.id)}:text, ${values.add(r.name)}:text, ${values.add(r.sponsorId)}:text, ${values.add(r.date)}:int8 )').join(', ')} )\n'
'AS UPDATED("id", "name", "sponsor_id", "date")\n'
'WHERE "parties"."id" = UPDATED."id"',
values.values,
await db.execute(
Sql.named('UPDATE "parties"\n'
'SET "name" = COALESCE(UPDATED."name", "parties"."name"), "sponsor_id" = COALESCE(UPDATED."sponsor_id", "parties"."sponsor_id"), "date" = COALESCE(UPDATED."date", "parties"."date")\n'
'FROM ( VALUES ${requests.map((r) => '( ${values.add(r.id)}:text::text, ${values.add(r.name)}:text::text, ${values.add(r.sponsorId)}:text::text, ${values.add(r.date)}:int8::int8 )').join(', ')} )\n'
'AS UPDATED("id", "name", "sponsor_id", "date")\n'
'WHERE "parties"."id" = UPDATED."id"'),
parameters: values.values,
);
}
}
Expand Down
24 changes: 15 additions & 9 deletions lib/src/builder/elements/column/column_element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:collection/collection.dart';
import 'package:postgres/postgres.dart';
import 'package:source_gen/source_gen.dart';

import '../../schema.dart';
Expand Down Expand Up @@ -80,21 +81,26 @@ abstract class ColumnElement {
void checkConverter();

late List<ConstantReader> modifiers = () {
if (parameter == null || parameter!.getter == null) return <ConstantReader>[];
final parameter = this.parameter;
final parameterGetter = parameter?.getter;
if (parameter == null || parameterGetter == null) return <ConstantReader>[];

return [
...hiddenInChecker.annotationsOf(parameter!),
...hiddenInChecker.annotationsOf(parameter!.getter!),
...viewedInChecker.annotationsOf(parameter!),
...viewedInChecker.annotationsOf(parameter!.getter!),
...transformedInChecker.annotationsOf(parameter!),
...transformedInChecker.annotationsOf(parameter!.getter!),
...hiddenInChecker.annotationsOf(parameter),
...hiddenInChecker.annotationsOf(parameterGetter),
...viewedInChecker.annotationsOf(parameter),
...viewedInChecker.annotationsOf(parameterGetter),
...transformedInChecker.annotationsOf(parameter),
...transformedInChecker.annotationsOf(parameterGetter),
].map((m) => ConstantReader(m)).toList();
}();

void checkModifiers();
}

final _dateTimeChecker = TypeChecker.fromRuntime(DateTime);
final _pointChecker = TypeChecker.fromRuntime(Point);

String? getSqlType(DartType type) {
if (type.isDartCoreString) {
return 'text';
Expand All @@ -104,9 +110,9 @@ String? getSqlType(DartType type) {
return 'float8';
} else if (type.isDartCoreBool) {
return 'boolean';
} else if (type.element?.name == 'DateTime') {
} else if (_dateTimeChecker.isExactlyType(type)) {
return 'timestamp';
} else if (type.element?.name == 'PgPoint') {
} else if (_pointChecker.isExactlyType(type)) {
return 'point';
} else {
return null;
Expand Down
4 changes: 3 additions & 1 deletion lib/src/builder/elements/table_element.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ class TableElement {

late List<FieldElement> allFields = element.fields
.cast<FieldElement>()
.followedBy(element.allSupertypes.expand((t) => t.isDartCoreObject ? [] : t.element.fields))
.followedBy(element.allSupertypes
.expand((t) => t.isDartCoreObject ? <FieldElement>[] : t.element.fields))
.where((e) => !e.hasInitializer)
.toList();

void prepareColumns() {
Expand Down
Loading
Loading