@bytebase/dbhub 0.0.8 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +34 -33
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +1489 -13
  4. package/dist/resources/employee-sqlite/employee.sql +117 -0
  5. package/dist/resources/employee-sqlite/load_department.sql +10 -0
  6. package/dist/resources/employee-sqlite/load_dept_emp.sql +1103 -0
  7. package/dist/resources/employee-sqlite/load_dept_manager.sql +17 -0
  8. package/dist/resources/employee-sqlite/load_employee.sql +1000 -0
  9. package/dist/resources/employee-sqlite/load_salary1.sql +9488 -0
  10. package/dist/resources/employee-sqlite/load_title.sql +1470 -0
  11. package/dist/resources/employee-sqlite/object.sql +74 -0
  12. package/dist/resources/employee-sqlite/show_elapsed.sql +4 -0
  13. package/dist/resources/employee-sqlite/test_employee_md5.sql +119 -0
  14. package/package.json +5 -4
  15. package/dist/config/demo-loader.js +0 -45
  16. package/dist/config/env.js +0 -146
  17. package/dist/connectors/interface.js +0 -55
  18. package/dist/connectors/manager.js +0 -91
  19. package/dist/connectors/mysql/index.js +0 -169
  20. package/dist/connectors/postgres/index.js +0 -172
  21. package/dist/connectors/sqlite/index.js +0 -208
  22. package/dist/connectors/sqlserver/index.js +0 -186
  23. package/dist/prompts/db-explainer.js +0 -201
  24. package/dist/prompts/index.js +0 -11
  25. package/dist/prompts/sql-generator.js +0 -114
  26. package/dist/resources/index.js +0 -12
  27. package/dist/resources/schema.js +0 -36
  28. package/dist/resources/tables.js +0 -17
  29. package/dist/server.js +0 -140
  30. package/dist/tools/index.js +0 -11
  31. package/dist/tools/list-connectors.js +0 -23
  32. package/dist/tools/run-query.js +0 -32
  33. package/dist/utils/response-formatter.js +0 -109
@@ -0,0 +1,74 @@
1
+ -- SQLite implementation of views and functions
2
+ -- This is simplified compared to the MySQL version
3
+
4
+ -- Drop views if they exist
5
+ DROP VIEW IF EXISTS v_full_employee;
6
+ DROP VIEW IF EXISTS v_full_department;
7
+ DROP VIEW IF EXISTS emp_dept_current;
8
+
9
+ -- Create helper view to get current department for employees
10
+ CREATE VIEW emp_dept_current AS
11
+ SELECT
12
+ e.emp_no,
13
+ de.dept_no
14
+ FROM
15
+ employee e
16
+ JOIN
17
+ dept_emp de ON e.emp_no = de.emp_no
18
+ JOIN (
19
+ SELECT
20
+ emp_no,
21
+ MAX(from_date) AS max_from_date
22
+ FROM
23
+ dept_emp
24
+ GROUP BY
25
+ emp_no
26
+ ) latest ON de.emp_no = latest.emp_no AND de.from_date = latest.max_from_date;
27
+
28
+ -- View that shows employee with their current department name
29
+ CREATE VIEW v_full_employee AS
30
+ SELECT
31
+ e.emp_no,
32
+ e.first_name,
33
+ e.last_name,
34
+ e.birth_date,
35
+ e.gender,
36
+ e.hire_date,
37
+ d.dept_name AS department
38
+ FROM
39
+ employee e
40
+ LEFT JOIN
41
+ emp_dept_current edc ON e.emp_no = edc.emp_no
42
+ LEFT JOIN
43
+ department d ON edc.dept_no = d.dept_no;
44
+
45
+ -- View to get current managers for departments
46
+ CREATE VIEW current_managers AS
47
+ SELECT
48
+ d.dept_no,
49
+ d.dept_name,
50
+ e.first_name || ' ' || e.last_name AS manager
51
+ FROM
52
+ department d
53
+ LEFT JOIN
54
+ dept_manager dm ON d.dept_no = dm.dept_no
55
+ JOIN (
56
+ SELECT
57
+ dept_no,
58
+ MAX(from_date) AS max_from_date
59
+ FROM
60
+ dept_manager
61
+ GROUP BY
62
+ dept_no
63
+ ) latest ON dm.dept_no = latest.dept_no AND dm.from_date = latest.max_from_date
64
+ LEFT JOIN
65
+ employee e ON dm.emp_no = e.emp_no;
66
+
67
+ -- Create a view showing departments with their managers
68
+ CREATE VIEW v_full_department AS
69
+ SELECT
70
+ dept_no,
71
+ dept_name,
72
+ manager
73
+ FROM
74
+ current_managers;
@@ -0,0 +1,4 @@
1
+ -- SQLite doesn't have information_schema like MySQL
2
+ -- This is a simpler version that just shows when the script was run
3
+
4
+ SELECT 'Database loaded at ' || datetime('now', 'localtime') AS completion_time;
@@ -0,0 +1,119 @@
1
+ -- Sample employee database
2
+ -- See changelog table for details
3
+ -- Copyright (C) 2007,2008, MySQL AB
4
+ --
5
+ -- Original data created by Fusheng Wang and Carlo Zaniolo
6
+ -- http://www.cs.aau.dk/TimeCenter/software.htm
7
+ -- http://www.cs.aau.dk/TimeCenter/Data/employeeTemporalDataSet.zip
8
+ --
9
+ -- Current schema by Giuseppe Maxia
10
+ -- Data conversion from XML to relational by Patrick Crews
11
+ -- SQLite adaptation by Claude Code
12
+ --
13
+ -- This work is licensed under the
14
+ -- Creative Commons Attribution-Share Alike 3.0 Unported License.
15
+ -- To view a copy of this license, visit
16
+ -- http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to
17
+ -- Creative Commons, 171 Second Street, Suite 300, San Francisco,
18
+ -- California, 94105, USA.
19
+ --
20
+ -- DISCLAIMER
21
+ -- To the best of our knowledge, this data is fabricated, and
22
+ -- it does not correspond to real people.
23
+ -- Any similarity to existing people is purely coincidental.
24
+ --
25
+
26
+ SELECT 'TESTING INSTALLATION' as 'INFO';
27
+
28
+ DROP TABLE IF EXISTS expected_value;
29
+ DROP TABLE IF EXISTS found_value;
30
+
31
+ CREATE TABLE expected_value (
32
+ table_name TEXT NOT NULL PRIMARY KEY,
33
+ recs INTEGER NOT NULL,
34
+ crc_md5 TEXT NOT NULL
35
+ );
36
+
37
+ CREATE TABLE found_value (
38
+ table_name TEXT NOT NULL PRIMARY KEY,
39
+ recs INTEGER NOT NULL,
40
+ crc_md5 TEXT NOT NULL
41
+ );
42
+
43
+ INSERT INTO expected_value VALUES
44
+ ('employee', 1000, '595460127fb609c2b110b1796083e242'),
45
+ ('department', 9, 'd1af5e170d2d1591d776d5638d71fc5f'),
46
+ ('dept_manager', 16, '8ff425d5ad6dc56975998d1893b8dca9'),
47
+ ('dept_emp', 1103, 'e302aa5b56a69b49e40eb0d60674addc'),
48
+ ('title', 1470, 'ba77dd331ce00f76c1643a7d73cdcee6'),
49
+ ('salary', 9488, '61f22cfece4d34f5bb94c9f05a3da3ef');
50
+
51
+ SELECT table_name, recs AS expected_record, crc_md5 AS expected_crc FROM expected_value;
52
+
53
+ DROP TABLE IF EXISTS tchecksum;
54
+ CREATE TABLE tchecksum (chk TEXT);
55
+
56
+ -- For SQLite, we need to use a different approach for MD5 calculation
57
+ -- Insert employee checksums
58
+ INSERT INTO found_value
59
+ SELECT 'employee', COUNT(*),
60
+ (SELECT hex(md5(group_concat(emp_no||birth_date||first_name||last_name||gender||hire_date, '#')))
61
+ FROM (SELECT * FROM employee ORDER BY emp_no))
62
+ FROM employee;
63
+
64
+ -- Insert department checksums
65
+ INSERT INTO found_value
66
+ SELECT 'department', COUNT(*),
67
+ (SELECT hex(md5(group_concat(dept_no||dept_name, '#')))
68
+ FROM (SELECT * FROM department ORDER BY dept_no))
69
+ FROM department;
70
+
71
+ -- Insert dept_manager checksums
72
+ INSERT INTO found_value
73
+ SELECT 'dept_manager', COUNT(*),
74
+ (SELECT hex(md5(group_concat(dept_no||emp_no||from_date||to_date, '#')))
75
+ FROM (SELECT * FROM dept_manager ORDER BY dept_no, emp_no))
76
+ FROM dept_manager;
77
+
78
+ -- Insert dept_emp checksums
79
+ INSERT INTO found_value
80
+ SELECT 'dept_emp', COUNT(*),
81
+ (SELECT hex(md5(group_concat(dept_no||emp_no||from_date||to_date, '#')))
82
+ FROM (SELECT * FROM dept_emp ORDER BY dept_no, emp_no))
83
+ FROM dept_emp;
84
+
85
+ -- Insert title checksums
86
+ INSERT INTO found_value
87
+ SELECT 'title', COUNT(*),
88
+ (SELECT hex(md5(group_concat(emp_no||title||from_date||IFNULL(to_date,''), '#')))
89
+ FROM (SELECT * FROM title ORDER BY emp_no, title, from_date))
90
+ FROM title;
91
+
92
+ -- Insert salary checksums
93
+ INSERT INTO found_value
94
+ SELECT 'salary', COUNT(*),
95
+ (SELECT hex(md5(group_concat(emp_no||amount||from_date||to_date, '#')))
96
+ FROM (SELECT * FROM salary ORDER BY emp_no, from_date, to_date))
97
+ FROM salary;
98
+
99
+ SELECT table_name, recs as 'found_records', crc_md5 as found_crc FROM found_value;
100
+
101
+ -- Compare expected vs found
102
+ SELECT
103
+ e.table_name,
104
+ CASE WHEN e.recs=f.recs THEN 'OK' ELSE 'not ok' END AS records_match,
105
+ CASE WHEN e.crc_md5=f.crc_md5 THEN 'ok' ELSE 'not ok' END AS crc_match
106
+ FROM
107
+ expected_value e
108
+ JOIN found_value f USING (table_name);
109
+
110
+ -- Check for failures
111
+ SELECT
112
+ 'CRC' as summary,
113
+ CASE WHEN (SELECT COUNT(*) FROM expected_value e JOIN found_value f USING(table_name) WHERE f.crc_md5 != e.crc_md5) = 0
114
+ THEN 'OK' ELSE 'FAIL' END as 'result'
115
+ UNION ALL
116
+ SELECT
117
+ 'count',
118
+ CASE WHEN (SELECT COUNT(*) FROM expected_value e JOIN found_value f USING(table_name) WHERE f.recs != e.recs) = 0
119
+ THEN 'OK' ELSE 'FAIL' END;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebase/dbhub",
3
- "version": "0.0.8",
3
+ "version": "0.1.1",
4
4
  "description": "Universal Database MCP Server",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -17,22 +17,23 @@
17
17
  "license": "MIT",
18
18
  "dependencies": {
19
19
  "@modelcontextprotocol/sdk": "^1.6.1",
20
- "@types/sqlite3": "^5.1.0",
20
+ "better-sqlite3": "^11.9.0",
21
21
  "dotenv": "^16.4.7",
22
22
  "express": "^4.18.2",
23
23
  "mssql": "^11.0.1",
24
24
  "mysql2": "^3.13.0",
25
25
  "pg": "^8.13.3",
26
- "sqlite3": "^5.1.7",
27
26
  "zod": "^3.24.2"
28
27
  },
29
28
  "devDependencies": {
29
+ "@types/better-sqlite3": "^7.6.12",
30
30
  "@types/express": "^4.17.21",
31
31
  "@types/mssql": "^9.1.7",
32
32
  "@types/node": "^22.13.10",
33
33
  "@types/pg": "^8.11.11",
34
34
  "cross-env": "^7.0.3",
35
35
  "ts-node": "^10.9.2",
36
+ "tsup": "^8.4.0",
36
37
  "tsx": "^4.19.3",
37
38
  "typescript": "^5.8.2"
38
39
  },
@@ -49,7 +50,7 @@
49
50
  "src/**/*"
50
51
  ],
51
52
  "scripts": {
52
- "build": "tsc",
53
+ "build": "tsup",
53
54
  "start": "node dist/index.js",
54
55
  "dev": "NODE_ENV=development tsx src/index.ts",
55
56
  "crossdev": "cross-env NODE_ENV=development tsx src/index.ts"
@@ -1,45 +0,0 @@
1
- /**
2
- * Demo data loader for SQLite in-memory database
3
- *
4
- * This module loads the sample employee database into the SQLite in-memory database
5
- * when the --demo flag is specified.
6
- */
7
- import fs from 'fs';
8
- import path from 'path';
9
- import { fileURLToPath } from 'url';
10
- // Create __dirname equivalent for ES modules
11
- const __filename = fileURLToPath(import.meta.url);
12
- const __dirname = path.dirname(__filename);
13
- // Path to sample data files
14
- const DEMO_DATA_DIR = path.join(__dirname, '..', '..', 'resources', 'employee-sqlite');
15
- /**
16
- * Load SQL file contents
17
- */
18
- export function loadSqlFile(fileName) {
19
- const filePath = path.join(DEMO_DATA_DIR, fileName);
20
- return fs.readFileSync(filePath, 'utf8');
21
- }
22
- /**
23
- * Get SQLite DSN for in-memory database
24
- */
25
- export function getInMemorySqliteDSN() {
26
- return 'sqlite::memory:';
27
- }
28
- /**
29
- * Load SQL files sequentially
30
- */
31
- export function getSqliteInMemorySetupSql() {
32
- // First, load the schema
33
- let sql = loadSqlFile('employee.sql');
34
- // Replace .read directives with the actual file contents
35
- // This is necessary because in-memory SQLite can't use .read
36
- const readRegex = /\.read\s+([a-zA-Z0-9_]+\.sql)/g;
37
- let match;
38
- while ((match = readRegex.exec(sql)) !== null) {
39
- const includePath = match[1];
40
- const includeContent = loadSqlFile(includePath);
41
- // Replace the .read line with the file contents
42
- sql = sql.replace(match[0], includeContent);
43
- }
44
- return sql;
45
- }
@@ -1,146 +0,0 @@
1
- import dotenv from "dotenv";
2
- import path from 'path';
3
- import fs from 'fs';
4
- import { fileURLToPath } from 'url';
5
- // Create __dirname equivalent for ES modules
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
8
- // Parse command line arguments
9
- export function parseCommandLineArgs() {
10
- // Check if any args start with '--' (the way tsx passes them)
11
- const args = process.argv.slice(2);
12
- const parsedManually = {};
13
- for (let i = 0; i < args.length; i++) {
14
- const arg = args[i];
15
- if (arg.startsWith('--')) {
16
- const [key, value] = arg.substring(2).split('=');
17
- if (value) {
18
- // Handle --key=value format
19
- parsedManually[key] = value;
20
- }
21
- else if (i + 1 < args.length && !args[i + 1].startsWith('--')) {
22
- // Handle --key value format
23
- parsedManually[key] = args[i + 1];
24
- i++; // Skip the next argument as it's the value
25
- }
26
- else {
27
- // Handle --key format (boolean flag)
28
- parsedManually[key] = 'true';
29
- }
30
- }
31
- }
32
- // Just use the manually parsed args - removed parseArgs dependency for Node.js <18.3.0 compatibility
33
- return parsedManually;
34
- }
35
- /**
36
- * Load environment files from various locations
37
- * Returns the name of the file that was loaded, or null if none was found
38
- */
39
- export function loadEnvFiles() {
40
- // Determine if we're in development or production mode
41
- const isDevelopment = process.env.NODE_ENV === 'development' || process.argv[1]?.includes('tsx');
42
- // Select environment file names based on environment
43
- const envFileNames = isDevelopment
44
- ? ['.env.local', '.env'] // In development, try .env.local first, then .env
45
- : ['.env']; // In production, only look for .env
46
- // Build paths to check for environment files
47
- const envPaths = [];
48
- for (const fileName of envFileNames) {
49
- envPaths.push(fileName, // Current working directory
50
- path.join(__dirname, '..', '..', fileName), // Two levels up (src/config -> src -> root)
51
- path.join(process.cwd(), fileName) // Explicit current working directory
52
- );
53
- }
54
- // Try to load the first env file found from the prioritized locations
55
- for (const envPath of envPaths) {
56
- console.error(`Checking for env file: ${envPath}`);
57
- if (fs.existsSync(envPath)) {
58
- dotenv.config({ path: envPath });
59
- // Return the name of the file that was loaded
60
- return path.basename(envPath);
61
- }
62
- }
63
- return null;
64
- }
65
- /**
66
- * Check if demo mode is enabled from command line args
67
- * Returns true if --demo flag is provided
68
- */
69
- export function isDemoMode() {
70
- const args = parseCommandLineArgs();
71
- return args.demo === 'true';
72
- }
73
- /**
74
- * Resolve DSN from command line args, environment variables, or .env files
75
- * Returns the DSN and its source, or null if not found
76
- */
77
- export function resolveDSN() {
78
- // Get command line arguments
79
- const args = parseCommandLineArgs();
80
- // Check for demo mode first (highest priority)
81
- if (isDemoMode()) {
82
- // Will use in-memory SQLite with demo data
83
- return {
84
- dsn: 'sqlite::memory:',
85
- source: 'demo mode',
86
- isDemo: true
87
- };
88
- }
89
- // 1. Check command line arguments
90
- if (args.dsn) {
91
- return { dsn: args.dsn, source: 'command line argument' };
92
- }
93
- // 2. Check environment variables before loading .env
94
- if (process.env.DSN) {
95
- return { dsn: process.env.DSN, source: 'environment variable' };
96
- }
97
- // 3. Try loading from .env files
98
- const loadedEnvFile = loadEnvFiles();
99
- if (loadedEnvFile && process.env.DSN) {
100
- return { dsn: process.env.DSN, source: `${loadedEnvFile} file` };
101
- }
102
- return null;
103
- }
104
- /**
105
- * Resolve transport type from command line args or environment variables
106
- * Returns 'stdio' or 'sse', with 'stdio' as the default
107
- */
108
- export function resolveTransport() {
109
- // Get command line arguments
110
- const args = parseCommandLineArgs();
111
- // 1. Check command line arguments first (highest priority)
112
- if (args.transport) {
113
- const type = args.transport === 'sse' ? 'sse' : 'stdio';
114
- return { type, source: 'command line argument' };
115
- }
116
- // 2. Check environment variables
117
- if (process.env.TRANSPORT) {
118
- const type = process.env.TRANSPORT === 'sse' ? 'sse' : 'stdio';
119
- return { type, source: 'environment variable' };
120
- }
121
- // 3. Default to stdio
122
- return { type: 'stdio', source: 'default' };
123
- }
124
- /**
125
- * Resolve port from command line args or environment variables
126
- * Returns port number with 8080 as the default
127
- *
128
- * Note: The port option is only applicable when using --transport=sse
129
- * as it controls the HTTP server port for SSE connections.
130
- */
131
- export function resolvePort() {
132
- // Get command line arguments
133
- const args = parseCommandLineArgs();
134
- // 1. Check command line arguments first (highest priority)
135
- if (args.port) {
136
- const port = parseInt(args.port, 10);
137
- return { port, source: 'command line argument' };
138
- }
139
- // 2. Check environment variables
140
- if (process.env.PORT) {
141
- const port = parseInt(process.env.PORT, 10);
142
- return { port, source: 'environment variable' };
143
- }
144
- // 3. Default to 8080
145
- return { port: 8080, source: 'default' };
146
- }
@@ -1,55 +0,0 @@
1
- /**
2
- * Registry for available database connectors
3
- */
4
- export class ConnectorRegistry {
5
- /**
6
- * Register a new connector
7
- */
8
- static register(connector) {
9
- ConnectorRegistry.connectors.set(connector.id, connector);
10
- }
11
- /**
12
- * Get a connector by ID
13
- */
14
- static getConnector(id) {
15
- return ConnectorRegistry.connectors.get(id) || null;
16
- }
17
- /**
18
- * Get connector for a DSN string
19
- * Tries to find a connector that can handle the given DSN format
20
- */
21
- static getConnectorForDSN(dsn) {
22
- for (const connector of ConnectorRegistry.connectors.values()) {
23
- if (connector.dsnParser.isValidDSN(dsn)) {
24
- return connector;
25
- }
26
- }
27
- return null;
28
- }
29
- /**
30
- * Get all available connector IDs
31
- */
32
- static getAvailableConnectors() {
33
- return Array.from(ConnectorRegistry.connectors.keys());
34
- }
35
- /**
36
- * Get sample DSN for a specific connector
37
- */
38
- static getSampleDSN(connectorId) {
39
- const connector = ConnectorRegistry.getConnector(connectorId);
40
- if (!connector)
41
- return null;
42
- return connector.dsnParser.getSampleDSN();
43
- }
44
- /**
45
- * Get all available sample DSNs
46
- */
47
- static getAllSampleDSNs() {
48
- const samples = {};
49
- for (const [id, connector] of ConnectorRegistry.connectors.entries()) {
50
- samples[id] = connector.dsnParser.getSampleDSN();
51
- }
52
- return samples;
53
- }
54
- }
55
- ConnectorRegistry.connectors = new Map();
@@ -1,91 +0,0 @@
1
- import { ConnectorRegistry } from './interface.js';
2
- // Singleton instance for global access
3
- let managerInstance = null;
4
- /**
5
- * Manages database connectors and provides a unified interface to work with them
6
- */
7
- export class ConnectorManager {
8
- constructor() {
9
- this.activeConnector = null;
10
- this.connected = false;
11
- if (!managerInstance) {
12
- managerInstance = this;
13
- }
14
- }
15
- /**
16
- * Initialize and connect to the database using a DSN
17
- */
18
- async connectWithDSN(dsn, initScript) {
19
- // First try to find a connector that can handle this DSN
20
- let connector = ConnectorRegistry.getConnectorForDSN(dsn);
21
- if (!connector) {
22
- throw new Error(`No connector found that can handle the DSN: ${dsn}`);
23
- }
24
- this.activeConnector = connector;
25
- // Connect to the database
26
- await this.activeConnector.connect(dsn, initScript);
27
- this.connected = true;
28
- }
29
- /**
30
- * Initialize and connect to the database using a specific connector type
31
- */
32
- async connectWithType(connectorType, dsn) {
33
- // Get the connector from the registry
34
- const connector = ConnectorRegistry.getConnector(connectorType);
35
- if (!connector) {
36
- throw new Error(`Connector "${connectorType}" not found`);
37
- }
38
- this.activeConnector = connector;
39
- // Use provided DSN or get sample DSN
40
- const connectionString = dsn || connector.dsnParser.getSampleDSN();
41
- // Connect to the database
42
- await this.activeConnector.connect(connectionString);
43
- this.connected = true;
44
- }
45
- /**
46
- * Close the database connection
47
- */
48
- async disconnect() {
49
- if (this.activeConnector && this.connected) {
50
- await this.activeConnector.disconnect();
51
- this.connected = false;
52
- }
53
- }
54
- /**
55
- * Get the active connector
56
- */
57
- getConnector() {
58
- if (!this.activeConnector) {
59
- throw new Error('No active connector. Call connectWithDSN() or connectWithType() first.');
60
- }
61
- return this.activeConnector;
62
- }
63
- /**
64
- * Check if there's an active connection
65
- */
66
- isConnected() {
67
- return this.connected;
68
- }
69
- /**
70
- * Get all available connector types
71
- */
72
- static getAvailableConnectors() {
73
- return ConnectorRegistry.getAvailableConnectors();
74
- }
75
- /**
76
- * Get sample DSNs for all available connectors
77
- */
78
- static getAllSampleDSNs() {
79
- return ConnectorRegistry.getAllSampleDSNs();
80
- }
81
- /**
82
- * Get the current active connector instance
83
- * This is used by resource and tool handlers
84
- */
85
- static getCurrentConnector() {
86
- if (!managerInstance) {
87
- throw new Error('ConnectorManager not initialized');
88
- }
89
- return managerInstance.getConnector();
90
- }
91
- }