Skip to content
Open
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
12 changes: 10 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ plugins {
id "com.github.johnrengelman.shadow" version "7.0.0"
}

version '1.20'
version '1.30'

repositories {
mavenCentral()
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation "org.mongodb:mongodb-driver-sync:4.11.1"
implementation "org.mongodb:mongodb-driver-sync:5.6.1"
implementation group: 'org.jetbrains', name: 'annotations', version: '15.0'
implementation group: 'org.apache.commons', name: 'commons-text', version: '1.10.0'
implementation group: 'org.graalvm.js', name: 'js', version: '22.3.1'
implementation files('libs/JMongosh-0.9.jar')
implementation group: 'com.nimbusds', name: 'oauth2-oidc-sdk', version: '11.+'
testImplementation group: 'junit', name: 'junit', version: '4.13.1'
testImplementation group: 'commons-io', name: 'commons-io', version: '2.7'
}
Expand All @@ -29,4 +30,11 @@ test {
shadowJar {
archiveFileName = "mongo-jdbc-standalone-${version}.jar"
mergeServiceFiles()
relocate 'com.nimbusds', 'shadow.com.nimbusds'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please describe the purpose of this change


relocate('org', 'shadow.org') {
exclude 'org.ow2.asm:.*'
exclude 'net.minidev:.*'
exclude 'org.javassist:.*'
}
}
233 changes: 123 additions & 110 deletions src/main/java/com/dbschema/MongoJdbcDriver.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package com.dbschema;

import com.dbschema.mongo.DriverPropertyInfoHelper;
import com.dbschema.mongo.MongoClientWrapper;
import com.dbschema.mongo.MongoConnection;
import com.dbschema.mongo.MongoService;
import com.dbschema.mongo.mongosh.LazyShellHolder;
import com.dbschema.mongo.mongosh.PrecalculatingShellHolder;
import com.dbschema.mongo.mongosh.ShellHolder;
import com.dbschema.mongo.oidc.OidcCallback;
import org.graalvm.polyglot.Engine;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.sql.*;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.logging.Logger;
Expand All @@ -28,127 +32,136 @@
* The URL excepting the jdbc: prefix is passed as it is to the MongoDb native Java driver.
*/
public class MongoJdbcDriver implements Driver {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes are hard to read because the diff includes unnecessary style edits (formatting, etc.). Please remove them or split the commits so that only the actual logic changes are visible

private final DriverPropertyInfoHelper propertyInfoHelper = new DriverPropertyInfoHelper();
private @Nullable ExecutorService executorService;
private @Nullable Engine sharedEngine;
private @NotNull ShellHolder shellHolder;

static {
try {
DriverManager.registerDriver(new MongoJdbcDriver());
private final DriverPropertyInfoHelper propertyInfoHelper = new DriverPropertyInfoHelper();
private @Nullable ExecutorService executorService;
private @Nullable Engine sharedEngine;
private @NotNull ShellHolder shellHolder;
private MongoConnection mongoConnection;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not cache the DB connection. If you need to cache the token, cache that instead


static {
try {
DriverManager.registerDriver(new MongoJdbcDriver());
} catch (SQLException ex) {
ex.printStackTrace();
}
}
catch (SQLException ex) {
ex.printStackTrace();

public MongoJdbcDriver() {
shellHolder = createShellHolder();
}
}

public MongoJdbcDriver() {
shellHolder = createShellHolder();
}
@NotNull
private ShellHolder createShellHolder() {
if ("true".equals(System.getProperty("mongosh.disableShellPrecalculation"))) {
return new LazyShellHolder();
}
if (executorService == null) {
executorService = newFixedThreadPool(10, newNamedThreadFactory("MongoShell ExecutorService"));
}
Engine engine = null;
if (!"true".equals(System.getProperty("mongosh.disableSharedEngine"))) {
if (sharedEngine == null) {
sharedEngine = Engine.create("js");
}
engine = sharedEngine;
}
return new PrecalculatingShellHolder(executorService, engine);
}

@NotNull
private ShellHolder createShellHolder() {
if ("true".equals(System.getProperty("mongosh.disableShellPrecalculation"))) {
return new LazyShellHolder();
/**
* Connect to the database using a URL like :
* jdbc:mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
* The URL excepting the jdbc: prefix is passed as it is to the MongoDb native Java driver.
*/
public Connection connect(String url, Properties info) throws SQLException {
if (url == null || !acceptsURL(url)) return null;

int fetchDocumentsForMeta = FETCH_DOCUMENTS_FOR_METAINFO_DEFAULT;
if (info.getProperty(FETCH_DOCUMENTS_FOR_METAINFO) != null) {
try {
fetchDocumentsForMeta = Integer.parseInt(info.getProperty(FETCH_DOCUMENTS_FOR_METAINFO));
} catch (NumberFormatException ignored) {
}
}
if (fetchDocumentsForMeta < 0) fetchDocumentsForMeta = 0;

if (url.startsWith("jdbc:")) {
url = url.substring("jdbc:".length());
}

String username = info.getProperty("user");
String password = info.getProperty("password");
synchronized (this) {
ShellHolder shellHolder = this.shellHolder;
this.shellHolder = createShellHolder();

var existingResult = Optional.ofNullable(this.mongoConnection)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use "var"

.map(MongoConnection::getService)
.map(MongoService::getClient)
.map(MongoClientWrapper::getOidcCallback)
.map(OidcCallback::getCallbackContext)
.orElse(null);

this.mongoConnection = new MongoConnection(url, info, username, password, fetchDocumentsForMeta, shellHolder, existingResult);

return this.mongoConnection;
}
}
if (executorService == null) {
executorService = newFixedThreadPool(10, newNamedThreadFactory("MongoShell ExecutorService"));


/**
* URLs accepted are of the form: jdbc:mongodb[+srv]://<server>[:27017]/<db-name>
*
* @see java.sql.Driver#acceptsURL(java.lang.String)
*/
@Override
public boolean acceptsURL(String url) {
if (url.startsWith("jdbc:")) {
url = url.substring("jdbc:".length());
}
return url.startsWith("mongodb://") || url.startsWith("mongodb+srv://");
}
Engine engine = null;
if (!"true".equals(System.getProperty("mongosh.disableSharedEngine"))) {
if (sharedEngine == null) {
sharedEngine = Engine.create("js");
}
engine = sharedEngine;

/**
* @see java.sql.Driver#getPropertyInfo(java.lang.String, java.util.Properties)
*/
@Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
return propertyInfoHelper.getPropertyInfo();
}
return new PrecalculatingShellHolder(executorService, engine);
}

/**
* Connect to the database using a URL like :
* jdbc:mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
* The URL excepting the jdbc: prefix is passed as it is to the MongoDb native Java driver.
*/
public Connection connect(String url, Properties info) throws SQLException {
if (url == null || !acceptsURL(url)) return null;

int fetchDocumentsForMeta = FETCH_DOCUMENTS_FOR_METAINFO_DEFAULT;
if (info.getProperty(FETCH_DOCUMENTS_FOR_METAINFO) != null) {
try {
fetchDocumentsForMeta = Integer.parseInt(info.getProperty(FETCH_DOCUMENTS_FOR_METAINFO));
}
catch (NumberFormatException ignored) {
}

/**
* @see java.sql.Driver#getMajorVersion()
*/
@Override
public int getMajorVersion() {
return 1;
}

/**
* @see java.sql.Driver#getMinorVersion()
*/
@Override
public int getMinorVersion() {
return 0;
}
if (fetchDocumentsForMeta < 0) fetchDocumentsForMeta = 0;

if (url.startsWith("jdbc:")) {
url = url.substring("jdbc:".length());
/**
* @see java.sql.Driver#jdbcCompliant()
*/
@Override
public boolean jdbcCompliant() {
return true;
}

String username = info.getProperty("user");
String password = info.getProperty("password");
synchronized (this) {
ShellHolder shellHolder = this.shellHolder;
this.shellHolder = createShellHolder();
return new MongoConnection(url, info, username, password, fetchDocumentsForMeta, shellHolder);
@Override
public Logger getParentLogger() {
return null;
}
}


/**
* URLs accepted are of the form: jdbc:mongodb[+srv]://<server>[:27017]/<db-name>
*
* @see java.sql.Driver#acceptsURL(java.lang.String)
*/
@Override
public boolean acceptsURL(String url) {
if (url.startsWith("jdbc:")) {
url = url.substring("jdbc:".length());

public void close() {
shellHolder.close();
if (sharedEngine != null) sharedEngine.close();
if (executorService != null) executorService.shutdownNow();
}
return url.startsWith("mongodb://") || url.startsWith("mongodb+srv://");
}

/**
* @see java.sql.Driver#getPropertyInfo(java.lang.String, java.util.Properties)
*/
@Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
return propertyInfoHelper.getPropertyInfo();
}

/**
* @see java.sql.Driver#getMajorVersion()
*/
@Override
public int getMajorVersion() {
return 1;
}

/**
* @see java.sql.Driver#getMinorVersion()
*/
@Override
public int getMinorVersion() {
return 0;
}

/**
* @see java.sql.Driver#jdbcCompliant()
*/
@Override
public boolean jdbcCompliant() {
return true;
}

@Override
public Logger getParentLogger() {
return null;
}

public void close() {
shellHolder.close();
if (sharedEngine != null) sharedEngine.close();
if (executorService != null) executorService.shutdownNow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

public class DriverPropertyInfoHelper {
public static final String AUTH_MECHANISM = "authMechanism";
public static final String[] AUTH_MECHANISM_CHOICES = new String[]{"GSSAPI", "MONGODB-AWS", "MONGODB-X509", "PLAIN", "SCRAM-SHA-1", "SCRAM-SHA-256"};
public static final String[] AUTH_MECHANISM_CHOICES = new String[]{"GSSAPI", "MONGODB-AWS", "MONGODB-X509", "PLAIN", "SCRAM-SHA-1", "SCRAM-SHA-256", "MONGODB-OIDC"};
public static final String AUTH_SOURCE = "authSource";
public static final String AWS_SESSION_TOKEN = "AWS_SESSION_TOKEN";
public static final String SERVICE_NAME = "SERVICE_NAME";
Expand Down
Loading