Skip to content

Commit b670e5e

Browse files
author
Isaque Neves
committed
add option to decode timestamp without timezone and date as local DateTime and decode timestamp with timezone respecting the timezone defined in the connection
1 parent dd67289 commit b670e5e

File tree

15 files changed

+361
-218
lines changed

15 files changed

+361
-218
lines changed

CHANGELOG.md

+30-1
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,33 @@ final manager = Manager();
9494

9595
## 3.3.0
9696

97-
- **Breaking change**: decode timestamp without timezone as local DateTime and decode timestamp with timezone respecting the timezone defined in the connection
97+
- add option to decode timestamp without timezone and date as local DateTime and decode timestamp with timezone respecting the timezone defined in the connection
98+
```dart
99+
final manager = Manager();
100+
manager.addConnection({
101+
'driver': 'pgsql',
102+
'driver_implementation': 'postgres_v3', // postgres | dargres | postgres_v3
103+
'timezone': 'America/Sao_Paulo',
104+
// If true, decodes the timestamp with timezone (timestamptz) as UTC = default
105+
// If false, decodes the timestamp with timezone using the timezone defined in the connection.
106+
'forceDecodeTimestamptzAsUTC': false,
107+
// If true, decodes the timestamp without timezone (timestamp) as UTC.
108+
// If false, decodes the timestamp without timezone as local datetime.
109+
'forceDecodeTimestampAsUTC': false,
110+
// If true, decodes the date as UTC.
111+
// If false, decodes the date as local datetime.
112+
'forceDecodeDateAsUTC': false,
113+
'pool': true,
114+
'poolsize': 2,
115+
'host': 'localhost',
116+
'port': '5435',
117+
'database': 'siamweb',
118+
'username': 'dart',
119+
'password': 'dart',
120+
'charset': 'win1252',
121+
'prefix': '',
122+
'schema': ['public'],
123+
// require | disable
124+
//'sslmode' : 'require',
125+
});
126+
```

README.md

+36
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,40 @@ void main(List<String> args) async {
240240
exit(0);
241241
}
242242

243+
```
244+
245+
## example of all settings
246+
247+
```dart
248+
final manager = Manager();
249+
manager.addConnection({
250+
'driver': 'pgsql',
251+
'driver_implementation': 'postgres_v3', // postgres | dargres | postgres_v3
252+
// set connection time zone UTC = default
253+
'timezone': 'America/Sao_Paulo',
254+
// If true, decodes the timestamp with timezone (timestamptz) as UTC = default
255+
// If false, decodes the timestamp with timezone using the timezone defined in the connection.
256+
'forceDecodeTimestamptzAsUTC': false,
257+
// If true, decodes the timestamp without timezone (timestamp) as UTC.
258+
// If false, decodes the timestamp without timezone as local datetime.
259+
'forceDecodeTimestampAsUTC': false,
260+
// If true, decodes the date as UTC.
261+
// If false, decodes the date as local datetime.
262+
'forceDecodeDateAsUTC': false,
263+
// enable connection pool
264+
'pool': true,
265+
// Connection pool maximum connection count
266+
'poolsize': 2,
267+
'host': 'localhost',
268+
'port': '5435',
269+
'database': 'siamweb',
270+
'username': 'dart',
271+
'password': 'dart',
272+
//
273+
'charset': 'win1252',
274+
'prefix': '',
275+
'schema': ['public'],
276+
// require | disable
277+
//'sslmode' : 'require',
278+
});
243279
```

example/bin/postgre_v2_example.dart

+27-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ void main(List<String> args) async {
66
final manager = Manager();
77
manager.addConnection({
88
'driver': 'pgsql',
9+
'driver_implementation': 'postgres_v3', // postgres | dargres | postgres_v3
10+
'timezone': 'America/Sao_Paulo',
11+
'forceDecodeTimestamptzAsUTC': false,
12+
'forceDecodeTimestampAsUTC': false,
13+
'forceDecodeDateAsUTC': false,
14+
'pool': true,
15+
'poolsize': 2,
916
'host': 'localhost',
1017
'port': '5435',
1118
'database': 'siamweb',
@@ -19,14 +26,27 @@ void main(List<String> args) async {
1926

2027
manager.setAsGlobal();
2128

22-
final db = await manager.connection();
29+
final connection = await manager.connection();
2330

24-
final res = await db.transaction((ctx) async {
25-
await ctx.table('test_table').insert({'id':10,'name':'Jane Doe'});
26-
final res = await ctx.table('test_table').limit(2).get();
27-
return res;
28-
});
31+
var results =
32+
await connection.select("select current_timestamp, current_date ");
33+
print('results: ${results}');
34+
var currentTimestamp = results.first['current_timestamp'] as DateTime;
35+
print('dafault: $currentTimestamp ${currentTimestamp.timeZoneName}');
36+
print('local: ${currentTimestamp.toLocal()}');
37+
38+
// await connection.execute("set timezone to 'America/Sao_Paulo'");
39+
// results = await connection.execute("select current_timestamp");
40+
// currentTimestamp = results.first.first as DateTime;
41+
// print(
42+
// 'America/Sao_Paulo: $currentTimestamp ${currentTimestamp.timeZoneName}');
43+
44+
// final res = await db.transaction((ctx) async {
45+
// await ctx.table('test_table').insert({'id':10,'name':'Jane Doe'});
46+
// final res = await ctx.table('test_table').limit(2).get();
47+
// return res;
48+
// });
49+
// print('res $res');
2950

30-
print('res $res');
3151
exit(0);
3252
}

lib/eloquent.dart

+1-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ export 'src/query/query_builder.dart';
55

66
export 'src/query/join_clause.dart';
77

8-
9-
108
export 'src/grammar.dart'; //BaseGrammar
119
export 'src/query/grammars/query_grammar.dart';
1210
export 'src/query/processors/processor.dart';
@@ -40,9 +38,9 @@ export 'src/exceptions/query_exception.dart';
4038

4139
//PDO
4240

43-
4441
export 'src/pdo/core/pdo_execution_context.dart';
4542
export 'src/pdo/core/pdo_result.dart';
4643
export 'src/pdo/core/pdo_interface.dart';
44+
export 'src/pdo/core/pdo_config.dart';
4745

4846
export '/src/pdo/core/constants.dart';

lib/src/capsule/manager.dart

+5-1
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ class Manager {
152152
/// @param array $config
153153
/// @param string $name
154154
/// @return void
155-
///
155+
///
156+
/// ```dart
157+
///
158+
/// ```
159+
///
156160
void addConnection(Map<String, dynamic> config, [String name = 'default']) {
157161
var connections = this.container['config']['database.connections'];
158162
if (connections == null) {

lib/src/connectors/connector.dart

+1-15
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ abstract class Connector with DetectsLostConnections {
1616
///
1717
Map<dynamic, dynamic> getOptions(Map<dynamic, dynamic> config) {
1818
var optionsP = config['options'];
19-
2019
//return array_diff_key(options, optionsP) + $options;
2120
//Utils.map_merge_sd(options, optionsP);
2221
if (optionsP != null) {
@@ -33,18 +32,5 @@ abstract class Connector with DetectsLostConnections {
3332
/// @param array $options
3433
/// @return \PDO
3534
///
36-
dynamic createConnection(
37-
String dsn, Map<String, dynamic> config, Map<String, dynamic> options);
38-
// var username = config['username'];
39-
//var password = config['password'];
40-
41-
// try {
42-
// $pdo = new PDO($dsn, $username, $password, $options);
43-
// } catch (Exception e) {
44-
// $pdo = $this->tryAgainIfCausedByLostConnection(
45-
// $e, $dsn, $username, $password, $options
46-
// );
47-
// }
48-
49-
//}
35+
dynamic createConnection(Map<String, dynamic> config);
5036
}

lib/src/connectors/mysql_connector.dart

+6-13
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ class MySqlConnector extends Connector implements ConnectorInterface {
1717
/// @return PostgreSQLConnection \PDO
1818
///
1919
Future<PDOInterface> connect(Map<String, dynamic> config) async {
20-
final dsn = getDsn(config);
21-
final options = getOptions(config);
22-
23-
final connection = await createConnection(dsn, config, options);
20+
//final dsn = getDsn(config);
21+
//final options = getOptions(config);
22+
final connection = await createConnection(config);
2423

2524
if (config.containsKey('database') && config['database'] != null) {
2625
await connection.execute("use `${config['database']}`;");
@@ -150,18 +149,12 @@ class MySqlConnector extends Connector implements ConnectorInterface {
150149
/// @return \PDO
151150
/// Aqui que cria a conexão com o Banco de Dados de fato
152151
///
153-
Future<PDOInterface> createConnection(String dsn, Map<dynamic, dynamic> config,
154-
Map<dynamic, dynamic> options) async {
155-
final username = config['username'];
156-
final password = config['password'];
157-
152+
Future<PDOInterface> createConnection(Map<String, dynamic> config) async {
158153
late PDOInterface pdo;
159154

160-
// if (config['driver_implementation'] == 'postgres') {
161-
// pdo = MySqlClientPDO(dsn, username, password, options);
162-
155+
final pdoConfig = PDOConfig.fromMap(config);
163156

164-
pdo = MySqlClientPDO(dsn, username, password,options);
157+
pdo = MySqlClientPDO(pdoConfig);
165158

166159
await pdo.connect();
167160

lib/src/connectors/postgres_connector.dart

+14-23
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,9 @@ class PostgresConnector extends Connector implements ConnectorInterface {
2222
// using the configuration option specified by the developer. We will also
2323
// set the default character set on the connections to UTF-8 by default.
2424

25-
var dsn = getDsn(config);
26-
27-
var options = getOptions(config);
28-
29-
var connection = await createConnection(dsn, config, options);
25+
//var dsn = getDsn(config);
26+
//var options = getOptions(config);
27+
var connection = await createConnection(config);
3028

3129
// if (config.containsKey('charset') && config['charset'] != null) {
3230
// var charset = config['charset'];
@@ -157,29 +155,22 @@ class PostgresConnector extends Connector implements ConnectorInterface {
157155
/// @return \PDO
158156
/// Aqui que cria a conexão com o Banco de Dados de fato
159157
///
160-
Future<PDOInterface> createConnection(String dsn, Map<String, dynamic> config,
161-
Map<dynamic, dynamic> options) async {
162-
final username = config['username'];
163-
final password = config['password'];
164-
// var host = config['host'];
165-
// var port = config['port']; //5432
166-
// var database = config['database'];
167-
// try {
168-
// $pdo = new PDO($dsn, $username, $password, $options);
169-
// } catch (Exception e) {
170-
// $pdo = $this->tryAgainIfCausedByLostConnection(
171-
// $e, $dsn, $username, $password, $options
172-
// );
173-
// }
158+
Future<PDOInterface> createConnection(Map<String, dynamic> config) async {
159+
//print('postgres_connector@createConnection config: $config');
160+
161+
if (config.containsKey('schema')) {
162+
config['schema'] = formatSchema(config['schema']);
163+
}
164+
final pdoConfig = PDOConfig.fromMap(config);
174165
late PDOInterface pdo;
175166
if (config['driver_implementation'] == 'postgres') {
176-
pdo = PostgresPDO(dsn, username, password, options);
167+
pdo = PostgresPDO(pdoConfig);
177168
} else if (config['driver_implementation'] == 'postgres_v3') {
178-
pdo = PostgresV3PDO(dsn, username, password, options);
169+
pdo = PostgresV3PDO(pdoConfig);
179170
} else if (config['driver_implementation'] == 'dargres') {
180-
pdo = DargresPDO(dsn, username, password, options);
171+
pdo = DargresPDO(pdoConfig);
181172
} else {
182-
pdo = PostgresPDO(dsn, username, password, options);
173+
pdo = PostgresPDO(pdoConfig);
183174
}
184175
await pdo.connect();
185176
return pdo;

lib/src/pdo/core/pdo_config.dart

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
class PDOConfig {
2+
final String driver;
3+
final String host;
4+
final int port;
5+
final String database;
6+
final String? username;
7+
final String? password;
8+
final bool? isUnixSocket;
9+
/// win1252 | utf8 | utf8mb4_general_ci
10+
final String? charset;
11+
12+
/// enable pool ?
13+
final bool? pool;
14+
final int? poolSize;
15+
String? applicationName;
16+
final bool? allowReconnect;
17+
18+
/// require | disable
19+
String? sslmode;
20+
/// UTC | America/Sao_Paulo
21+
String? timezone;
22+
String? schema;
23+
24+
/// If true, decodes the timestamp with timezone (timestamptz) as UTC.
25+
/// If false, decodes the timestamp with timezone using the timezone defined in the connection.
26+
bool forceDecodeTimestamptzAsUTC = true;
27+
28+
/// If true, decodes the timestamp without timezone (timestamp) as UTC.
29+
/// If false, decodes the timestamp without timezone as local datetime.
30+
bool forceDecodeTimestampAsUTC = true;
31+
32+
/// If true, decodes the date as UTC.
33+
/// If false, decodes the date as local datetime.
34+
bool forceDecodeDateAsUTC = true;
35+
36+
PDOConfig({
37+
required this.driver,
38+
required this.host,
39+
this.port = 5432,
40+
required this.database,
41+
this.username,
42+
this.password,
43+
this.isUnixSocket = false,
44+
this.pool = false,
45+
this.poolSize = 1,
46+
this.applicationName,
47+
this.charset = 'utf8',
48+
this.allowReconnect,
49+
this.sslmode,
50+
this.timezone,
51+
this.schema,
52+
this.forceDecodeTimestamptzAsUTC = true,
53+
this.forceDecodeTimestampAsUTC = true,
54+
this.forceDecodeDateAsUTC = true,
55+
});
56+
57+
Map<String, dynamic> toMap() {
58+
return <String, dynamic>{
59+
'driver': driver,
60+
'host': host,
61+
'port': port,
62+
'database': database,
63+
'username': username,
64+
'password': password,
65+
'isUnixSocket': isUnixSocket,
66+
'charset': charset,
67+
'pool': pool,
68+
'poolsize': poolSize,
69+
'applicationName': applicationName,
70+
'allowReconnect': allowReconnect,
71+
'sslmode': sslmode,
72+
'timezone': timezone,
73+
'schema': schema,
74+
'forceDecodeTimestamptzAsUTC': forceDecodeTimestamptzAsUTC,
75+
'forceDecodeTimestampAsUTC': forceDecodeTimestampAsUTC,
76+
'forceDecodeDateAsUTC': forceDecodeDateAsUTC,
77+
};
78+
}
79+
80+
factory PDOConfig.fromMap(Map<String, dynamic> map) {
81+
final config = PDOConfig(
82+
driver: map['driver'],
83+
host: map['host'],
84+
port: map['port'] is int ? map['port'] : int.parse(map['port']),
85+
database: map['database'],
86+
username: map['username'],
87+
password: map['password'],
88+
isUnixSocket: map['is_unix_socket'],
89+
charset: map['charset'],
90+
pool: map['pool'],
91+
poolSize: map['poolsize'],
92+
applicationName: map['application_name'],
93+
allowReconnect: map['allowreconnect'],
94+
sslmode: map['sslmode'],
95+
timezone: map['timezone'],
96+
schema: map['schema'],
97+
);
98+
if (map['forceDecodeTimestamptzAsUTC'] is bool) {
99+
config.forceDecodeTimestamptzAsUTC = map['forceDecodeTimestamptzAsUTC'];
100+
}
101+
if (map['forceDecodeTimestampAsUTC'] is bool) {
102+
config.forceDecodeTimestampAsUTC = map['forceDecodeTimestampAsUTC'];
103+
}
104+
if (map['forceDecodeDateAsUTC'] is bool) {
105+
config.forceDecodeDateAsUTC = map['forceDecodeDateAsUTC'];
106+
}
107+
108+
return config;
109+
}
110+
}

0 commit comments

Comments
 (0)