Skip to content

Commit af5e332

Browse files
committed
under dart_gdbc standard.
0 parents  commit af5e332

22 files changed

+425
-0
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
.dart_tool/
3+
.vscode/
4+
5+
**/pubspec.lock

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 1.0.0
2+
3+
- Initial version.

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
A sample command-line application with an entrypoint in `bin/`, library code
2+
in `lib/`, and example unit test in `test/`.

analysis_options.yaml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This file configures the static analysis results for your project (errors,
2+
# warnings, and lints).
3+
#
4+
# This enables the 'recommended' set of lints from `package:lints`.
5+
# This set helps identify many issues that may lead to problems when running
6+
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
7+
# style and format.
8+
#
9+
# If you want a smaller set of lints you can change this to specify
10+
# 'package:lints/core.yaml'. These are just the most critical lints
11+
# (the recommended set includes the core lints).
12+
# The core lints are also what is used by pub.dev for scoring packages.
13+
14+
include: package:lints/recommended.yaml
15+
16+
# Uncomment the following section to specify additional rules.
17+
18+
# linter:
19+
# rules:
20+
# - camel_case_types
21+
22+
# analyzer:
23+
# exclude:
24+
# - path/to/excluded/files/**
25+
26+
# For more information about the core and recommended set of lints, see
27+
# https://dart.dev/go/core-lints
28+
29+
# For additional information about configuring this file, see
30+
# https://dart.dev/guides/language/analysis-options

bin/nebula_dart_gdbc.dart

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import 'package:nebula_dart_gdbc/nebula_dart_gdbc.dart' as nebula_dart_gdbc;
2+
3+
void main(List<String> arguments) {}

example/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# https://dart.dev/guides/libraries/private-files
2+
# Created by `dart pub`
3+
.dart_tool/

example/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 1.0.0
2+
3+
- Initial version.

example/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
A sample command-line application with an entrypoint in `bin/`, library code
2+
in `lib/`, and example unit test in `test/`.

example/analysis_options.yaml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This file configures the static analysis results for your project (errors,
2+
# warnings, and lints).
3+
#
4+
# This enables the 'recommended' set of lints from `package:lints`.
5+
# This set helps identify many issues that may lead to problems when running
6+
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
7+
# style and format.
8+
#
9+
# If you want a smaller set of lints you can change this to specify
10+
# 'package:lints/core.yaml'. These are just the most critical lints
11+
# (the recommended set includes the core lints).
12+
# The core lints are also what is used by pub.dev for scoring packages.
13+
14+
include: package:lints/recommended.yaml
15+
16+
# Uncomment the following section to specify additional rules.
17+
18+
# linter:
19+
# rules:
20+
# - camel_case_types
21+
22+
# analyzer:
23+
# exclude:
24+
# - path/to/excluded/files/**
25+
26+
# For more information about the core and recommended set of lints, see
27+
# https://dart.dev/go/core-lints
28+
29+
# For additional information about configuring this file, see
30+
# https://dart.dev/guides/language/analysis-options

example/bin/example.dart

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import 'package:example/example.dart' as example;
2+
3+
void main(List<String> arguments) {}

example/lib/example.dart

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// use driver
2+
3+
import 'package:nebula_dart_gdbc/nebula_dart_gdbc.dart';
4+
5+
void main(List<String> args) async {
6+
DriverManager.registerDriver(NgDriver());
7+
8+
var conn = await DriverManager.getConnection(
9+
'gdbc.nebula://127.0.0.1:9669/?username=root&password=nebula&space=test',
10+
properties: <String, dynamic>{
11+
// properties is optional
12+
DriverManager.usrKey: 'root',
13+
DriverManager.pwdKey: 'nebula',
14+
'timeout': 1000,
15+
'space': 'test',
16+
},
17+
username: 'root', // username is optional
18+
password: 'nebula', // password is optional
19+
);
20+
21+
var stmt = await conn.createStatement();
22+
await conn.executeQuery('use test');
23+
var rs = await stmt.executeQuery('MATCH (n) RETURN n LIMIT 10;');
24+
25+
print(rs);
26+
await conn.close();
27+
}

example/pubspec.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: example
2+
description: A sample command-line application.
3+
version: 1.0.0
4+
publish_to: none
5+
6+
environment:
7+
sdk: '>=2.19.0 <3.0.0'
8+
9+
dependencies:
10+
nebula_dart_gdbc:
11+
path: ..
12+
13+
dev_dependencies:
14+
lints: ^2.0.0
15+
test: ^1.21.0

example/test/example_test.dart

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import 'package:example/example.dart';
2+
import 'package:test/test.dart';
3+
4+
void main() {}

lib/nebula_dart_gdbc.dart

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library nebula_dart_gdbc;
2+
3+
import 'dart:convert';
4+
import 'dart:typed_data';
5+
6+
import 'package:nebula_dart_gdbc/nebula_dart_gdbc.dart';
7+
import 'package:nebula_graph/nebula_graph.dart';
8+
9+
// export all dart_gdbc and alias it to gdbc
10+
export 'package:dart_gdbc/dart_gdbc.dart';
11+
12+
part 'src/ng_driver.dart';
13+
part 'src/ng_connection.dart';
14+
part 'src/ng_statement.dart';
15+
part 'src/ng_prepared_statement.dart';
16+
part 'src/ng_result_set.dart';
17+
part 'src/ng_result_set_meta_data.dart';

lib/src/ng_connection.dart

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
part of nebula_dart_gdbc;
2+
3+
/// Create by [DriverManager.getConnection]
4+
///
5+
/// 通过 [DriverManager.getConnection] 创建
6+
///
7+
/// For example:
8+
/// ```dart
9+
/// DriverManager.getConnection(
10+
/// 'gdbc.nebula://127.0.0.1:9669/?username=root&password=nebula&space=nb',
11+
/// properties: {// properties is optional
12+
/// DriverManager.usrKey: 'root',
13+
/// DriverManager.pwdKey: 'nebula',
14+
/// 'timeout': '1000',
15+
/// 'space': 'nb',
16+
/// },
17+
/// username: 'root', // username is optional
18+
/// password: 'nebula', // password is optional
19+
/// );
20+
/// ```
21+
class NgConnection implements Connection {
22+
static const String timeoutKey = 'timeout';
23+
24+
NgConnection._();
25+
26+
late TSocketTransport socketTransport;
27+
late TFramedTransport transport;
28+
late THeaderProtocol protocol;
29+
late GraphServiceClient client;
30+
late Map<String, dynamic> properties;
31+
int? _sessionId;
32+
int? timezoneOffset;
33+
int timeout = 0;
34+
35+
/// Invoked in [DriverManager.getConnection],
36+
/// you should not call this method directly.
37+
/// Because connection is not open yet.
38+
///
39+
/// 通过 [DriverManager.getConnection] 调用,
40+
/// 不应该直接调用这个方法。
41+
/// 因为连接还没有打开。
42+
NgConnection._create(Uri address, {Map<String, dynamic>? properties}) {
43+
this.properties = properties ?? <String, dynamic>{};
44+
socketTransport = TSocketTransport(
45+
host: address.host,
46+
port: address.port,
47+
connectionTimeout: properties?[timeoutKey] ?? 6000,
48+
);
49+
50+
transport = THeaderTransport(
51+
transport: socketTransport,
52+
clientTypes: [ClientTypes.HEADERS],
53+
supportedClients: [false]);
54+
55+
protocol = THeaderProtocol(transport);
56+
client = GraphServiceClient(protocol);
57+
}
58+
59+
/// Invoked in [DriverManager.getConnection], after the connection created.
60+
///
61+
/// 在 [DriverManager.getConnection] 内创建了连接之后调用。
62+
Future<void> _open() async {
63+
if (!socketTransport.isOpen) await socketTransport.open();
64+
65+
/// check the version of client and server
66+
await verifyVersion();
67+
await authencate();
68+
}
69+
70+
/// check the version of client and server
71+
/// if the version is not compatible, throw an exception
72+
///
73+
/// 检查客户端和服务端的版本是否兼容
74+
/// 如果不兼容,抛出异常
75+
Future<void> verifyVersion() async {
76+
VerifyClientVersionResp resp =
77+
await client.verifyClientVersion(VerifyClientVersionReq());
78+
79+
if (resp.error_code != ErrorCode.SUCCEEDED) {
80+
throw VersionException(
81+
message: String.fromCharCodes(resp.error_msg ?? []));
82+
}
83+
}
84+
85+
/// authenticate the user
86+
///
87+
/// 认证用户
88+
Future<void> authencate() async {
89+
AuthResponse resp = await client.authenticate(
90+
Int8List.fromList(utf8.encode(properties[DriverManager.usrKey] ?? '')),
91+
Int8List.fromList(utf8.encode(properties[DriverManager.pwdKey] ?? '')),
92+
);
93+
94+
if (resp.error_code != ErrorCode.SUCCEEDED) {
95+
if (resp.error_msg != null) {
96+
throw ConnectException(message: String.fromCharCodes(resp.error_msg!));
97+
} else {
98+
throw ConnectException(message: "Auth failed");
99+
}
100+
}
101+
102+
_sessionId = resp.session_id;
103+
timezoneOffset = resp.time_zone_offset_seconds ?? 0;
104+
}
105+
106+
@override
107+
Future<void> close() async {
108+
await transport.close();
109+
}
110+
111+
@override
112+
Future<void> commit() async {}
113+
114+
@override
115+
Future<Statement> createStatement() async {
116+
return NgStatement(this);
117+
}
118+
119+
@override
120+
Future<ResultSet> executeQuery(String gql) async {
121+
return await NgStatement(this).executeQuery(gql);
122+
}
123+
124+
@override
125+
Future<int> executeUpdate(String gql) async {
126+
return await NgStatement(this).executeUpdate(gql);
127+
}
128+
129+
@override
130+
Future<bool> getAutoCommit() async {
131+
return true;
132+
}
133+
134+
@override
135+
Future<ResultSetMetaData> getMetaData() {
136+
// TODO: implement getMetaData
137+
throw UnimplementedError();
138+
}
139+
140+
@override
141+
Future<bool> isClosed() async {
142+
return !transport.isOpen;
143+
}
144+
145+
@override
146+
Future<PreparedStatement> prepareStatement(String gql) async {
147+
return NgPreparedStatement(this);
148+
}
149+
150+
@override
151+
Future<PreparedStatement> prepareStatementWithParameters(
152+
String gql, List<ParameterMetaData> parameters) async {
153+
return NgPreparedStatement(this, parameters: parameters);
154+
}
155+
156+
@override
157+
Future<void> rollback() {
158+
throw DbFeatureException('No support for rollback');
159+
}
160+
161+
@override
162+
Future<void> setAutoCommit(bool autoCommit) {
163+
throw DbFeatureException('No support for setAutoCommit');
164+
}
165+
}

lib/src/ng_driver.dart

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
part of nebula_dart_gdbc;
2+
3+
class NgDriver extends Driver {
4+
@override
5+
bool acceptsURL(String url) {
6+
return url.startsWith('gdbc.nebula:');
7+
}
8+
9+
@override
10+
Future<Connection> connect(
11+
String url, {
12+
Map<String, dynamic>? properties,
13+
}) async {
14+
var address = _parseURL(url);
15+
address.queryParameters.forEach((key, value) {
16+
properties![key] = value;
17+
});
18+
print(properties);
19+
var conn = NgConnection._create(address, properties: properties);
20+
await conn._open();
21+
return conn;
22+
}
23+
24+
Uri _parseURL(String url) {
25+
var uri = Uri.parse(url);
26+
if (uri.scheme != 'gdbc.nebula' || uri.host.isEmpty || uri.port <= 0) {
27+
throw ArgumentError('Invalid URL: $url');
28+
}
29+
return uri;
30+
}
31+
}

lib/src/ng_prepared_statement.dart

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
part of nebula_dart_gdbc;
2+
3+
class NgPreparedStatement extends NgStatement implements PreparedStatement {
4+
List<ParameterMetaData>? parameters;
5+
NgPreparedStatement(super.conn, {this.parameters});
6+
7+
@override
8+
Future<bool> execute([String? gql, Map<String, dynamic>? params]) async {
9+
var rs = await executeQuery(gql, params);
10+
return rs.success;
11+
}
12+
13+
@override
14+
Future<ResultSet> executeQuery(
15+
[String? gql, Map<String, dynamic>? params]) async {
16+
return super.executeQuery(gql);
17+
}
18+
19+
@override
20+
Future<int> executeUpdate(String? gql, [Map<String, dynamic>? params]) async {
21+
return super.executeUpdate(gql);
22+
}
23+
}

lib/src/ng_result_set.dart

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
part of '../nebula_dart_gdbc.dart';
2+
3+
class NgResultSet extends ResultSet {}

lib/src/ng_result_set_meta_data.dart

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
part of '../nebula_dart_gdbc.dart';
2+
3+
class NgResultSetMetaData implements ResultSetMetaData {}

0 commit comments

Comments
 (0)