Added database connection retry
This commit is contained in:
parent
a5f4e4ff7a
commit
f0a5e7c6fc
12 changed files with 128 additions and 23 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -13,5 +13,6 @@
|
|||
},
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.markdownlint": true
|
||||
}
|
||||
},
|
||||
"cmake.configureOnOpen": false
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
name: angel_orm_sqlite
|
||||
environment:
|
||||
sdk: ">=2.16.0 <3.0.0"
|
||||
dependencies:
|
||||
angel_orm: ^2.0.0-dev
|
||||
|
|
30
docker/README.md
Normal file
30
docker/README.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Working with Docker
|
||||
|
||||
## Postgresql
|
||||
|
||||
### Starting the container
|
||||
|
||||
```bash
|
||||
docker-compose -f docker-compose-pg.yml up
|
||||
```
|
||||
|
||||
### Running psql
|
||||
|
||||
```bash
|
||||
docker exec -it <container id> /bin/bash
|
||||
psql --username postgres
|
||||
```
|
||||
|
||||
### Create database, user and access
|
||||
|
||||
```psql
|
||||
postgres=# create database orm_test;
|
||||
postgres=# create user test with encrypted password 'test123';
|
||||
postgres=# grant all privileges on database orm_test to test;
|
||||
```
|
||||
|
||||
## MariaDB
|
||||
|
||||
## MySQL
|
||||
|
||||
## Redis
|
21
docker/docker-compose-pg.yml
Normal file
21
docker/docker-compose-pg.yml
Normal file
|
@ -0,0 +1,21 @@
|
|||
version: "3.8"
|
||||
services:
|
||||
pgdb:
|
||||
image: postgres:latest
|
||||
restart: always
|
||||
ports:
|
||||
- "5432:5432"
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
volumes:
|
||||
- "db:/var/lib/postgresql/data"
|
||||
networks:
|
||||
- webnet
|
||||
|
||||
volumes:
|
||||
db:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
webnet:
|
|
@ -11,8 +11,8 @@ dependencies:
|
|||
args: ^2.1.0
|
||||
charcode: ^1.2.0
|
||||
postgres: ^2.4.0
|
||||
mysql_client: ^0.0.15
|
||||
mysql1: ^0.19.0
|
||||
mysql_client: ^0.0.24
|
||||
mysql1: ^0.20.0
|
||||
logging: ^1.0.0
|
||||
dev_dependencies:
|
||||
lints: ^2.0.0
|
||||
|
|
|
@ -8,8 +8,8 @@ environment:
|
|||
dependencies:
|
||||
angel3_orm: ^6.0.0
|
||||
logging: ^1.0.0
|
||||
mysql1: ^0.19.0
|
||||
mysql_client: ^0.0.15
|
||||
mysql1: ^0.20.0
|
||||
mysql_client: ^0.0.24
|
||||
optional: ^6.0.0
|
||||
dev_dependencies:
|
||||
angel3_orm_generator: ^6.0.0
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
## 6.0.1
|
||||
|
||||
* Upgraded to `lints` 2.x.x
|
||||
* Fixed #71. Create a new database connection and retry.
|
||||
|
||||
## 6.0.0
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'package:postgres/postgres.dart';
|
|||
|
||||
/// A [QueryExecutor] that queries a PostgreSQL database.
|
||||
class PostgreSqlExecutor extends QueryExecutor {
|
||||
final PostgreSQLExecutionContext _connection;
|
||||
PostgreSQLExecutionContext _connection;
|
||||
|
||||
/// An optional [Logger] to print information to. A default logger will be used
|
||||
/// if not set
|
||||
|
@ -57,7 +57,43 @@ class PostgreSqlExecutor extends QueryExecutor {
|
|||
}
|
||||
});
|
||||
|
||||
return _connection.query(query, substitutionValues: param);
|
||||
return _connection
|
||||
.query(query, substitutionValues: param)
|
||||
.catchError((err) async {
|
||||
logger.warning(err);
|
||||
if (err is PostgreSQLException) {
|
||||
// This is a hack to detect broken db connection
|
||||
bool brokenConnection =
|
||||
err.message?.contains("connection is not open") ?? false;
|
||||
if (brokenConnection) {
|
||||
if (_connection is PostgreSQLConnection) {
|
||||
// Open a new db connection
|
||||
var currentConnection = _connection as PostgreSQLConnection;
|
||||
currentConnection.close();
|
||||
|
||||
logger.warning(
|
||||
"A broken database connection is detected. Creating a new database connection.");
|
||||
var conn = _createNewConnection(currentConnection);
|
||||
await conn.open();
|
||||
_connection = conn;
|
||||
|
||||
// Retry the query with the new db connection
|
||||
return _connection.query(query, substitutionValues: param);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
// Create a new database connection from an existing connection
|
||||
PostgreSQLConnection _createNewConnection(PostgreSQLConnection conn) {
|
||||
return PostgreSQLConnection(conn.host, conn.port, conn.databaseName,
|
||||
username: conn.username,
|
||||
password: conn.password,
|
||||
useSSL: conn.useSSL,
|
||||
timeZone: conn.timeZone,
|
||||
timeoutInSeconds: conn.timeoutInSeconds);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
14
packages/orm/angel_orm_test/lib/src/models/boat.d.ts
vendored
Normal file
14
packages/orm/angel_orm_test/lib/src/models/boat.d.ts
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
declare module 'angel3_orm_test' {
|
||||
interface Boat {
|
||||
id?: string;
|
||||
created_at?: any;
|
||||
updated_at?: any;
|
||||
make?: string;
|
||||
description?: string;
|
||||
family_friendly?: boolean;
|
||||
recalled_at?: any;
|
||||
price?: number;
|
||||
width?: number;
|
||||
}
|
||||
}
|
|
@ -5,24 +5,24 @@ import 'package:optional/optional.dart';
|
|||
|
||||
part 'boat.g.dart';
|
||||
|
||||
@serializable
|
||||
@Serializable(serializers: Serializers.all)
|
||||
@orm
|
||||
abstract class _Boat extends Model {
|
||||
@SerializableField(defaultValue: '')
|
||||
@Column(defaultValue: '')
|
||||
String get make;
|
||||
|
||||
@SerializableField(defaultValue: 'none')
|
||||
@Column(defaultValue: 'none')
|
||||
String get description;
|
||||
|
||||
@SerializableField(defaultValue: false)
|
||||
@Column(defaultValue: false)
|
||||
bool get familyFriendly;
|
||||
|
||||
//@SerializableField(defaultValue: '1970-01-01 00:00:00')
|
||||
DateTime get recalledAt;
|
||||
|
||||
@SerializableField(defaultValue: 0.0)
|
||||
@Column(defaultValue: 0.0)
|
||||
double get price;
|
||||
|
||||
@SerializableField(defaultValue: 0)
|
||||
@Column(defaultValue: 0)
|
||||
int get width;
|
||||
}
|
||||
|
|
|
@ -234,12 +234,12 @@ class Boat extends _Boat {
|
|||
{this.id,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.make = '',
|
||||
this.description = 'none',
|
||||
this.familyFriendly = false,
|
||||
required this.make,
|
||||
required this.description,
|
||||
required this.familyFriendly,
|
||||
required this.recalledAt,
|
||||
this.price = 0.0,
|
||||
this.width = 0});
|
||||
required this.price,
|
||||
required this.width});
|
||||
|
||||
/// A unique identifier corresponding to this item.
|
||||
@override
|
||||
|
@ -372,16 +372,16 @@ class BoatSerializer extends Codec<Boat, Map> {
|
|||
? (map['updated_at'] as DateTime)
|
||||
: DateTime.parse(map['updated_at'].toString()))
|
||||
: null,
|
||||
make: map['make'] as String? ?? '',
|
||||
description: map['description'] as String? ?? 'none',
|
||||
familyFriendly: map['family_friendly'] as bool? ?? false,
|
||||
make: map['make'] as String,
|
||||
description: map['description'] as String,
|
||||
familyFriendly: map['family_friendly'] as bool,
|
||||
recalledAt: map['recalled_at'] != null
|
||||
? (map['recalled_at'] is DateTime
|
||||
? (map['recalled_at'] as DateTime)
|
||||
: DateTime.parse(map['recalled_at'].toString()))
|
||||
: DateTime.parse("1970-01-01 00:00:00"),
|
||||
price: map['price'] as double? ?? 0.0,
|
||||
width: map['width'] as int? ?? 0);
|
||||
price: map['price'] as double,
|
||||
width: map['width'] as int);
|
||||
}
|
||||
|
||||
static Map<String, dynamic> toMap(_Boat? model) {
|
||||
|
|
Loading…
Reference in a new issue