Is it possible to create a data source via an API?

We have a lot of database connections to keep track of. The connection parameters are defined in Chef data bags. I would like an easy way to use the chef data bags to create data sources in DataGrip. I successfully wrote a little python script to parse the data bags and spit out a dataSources.xml and dataSources.local.xml file but this has two drawbacks: 1) it does not enter the passwords since they are managed via keyrings and 2) it replaces the config you already have so you can't really use it if you have some custom connections already set up.

My thought was to write a plugin that would let you import a data source from the Chef data bag (JSON). I have a simple plugin and can use it to ask the user for files to import but I am not seeing a way to create a new data source. All of the database related interfaces seem to only expose read operations. (DbPsiFacade, DatabaseSystem, the deprecated DataSourceManager and DbDataSource, etc)

Am I missing something or is creating data sources not something that is exposed via the API for plugins to use?

4 comments
Comment actions Permalink

Checkout 

com.intellij.database.autoconfig.DataSourceDetector API and its extension point

"com.intellij.database.dataSourceDetector"

The data sources from Chef files can be thus imported via (+) | Import from Sources action.

 

Otherwise see

https://youtrack.jetbrains.com/issue/IJSDK-328

0
Comment actions Permalink

Thank you for the pointers. At first glance, the code in that issue doesn't seem to quite work but given that it was just recently posted, it is probably some classpath or project configuration thing on my end. I will have to look at it some more on our next hack day.

0
Comment actions Permalink

Ok, first of all, I had to manually add the database-impl.jar JAR file to the SDK classpath to get access to the data source related classes.

I haven't really been able to find any documentation on the DataSourceDetector API. There doesn't seem to be any javadoc available online and that class doesn't exist in the IntelliJ IDEA community edition git repo. Where am I not looking?

On the other hand, I was able to get manual data source creation working, like this:

String jdbcUrl = "jdbc:oracle:thin:@(DESCRIPTION = ....";
LocalDataSource ds = new LocalDataSource("Test Data Source", "oracle.jdbc.OracleDriver",
jdbcUrl, "database_user", "sekret");

Project currentProject = PlatformDataKeys.PROJECT.getData(
DataManager.getInstance().getDataContextFromFocus().getResult());

DefaultDbPsiManager psiManager = ContainerUtil.findInstance(
DbPsiFacade.getInstance(currentProject).getDbManagers(),
DefaultDbPsiManager.class);

psiManager.addDataSource(ds);

 

2
Comment actions Permalink

As I did work on the issue recently, I will put an updated version of the code based on the previous one.

In my case it was for a postgresql database:

String testUrl = "jdbc:postgresql://localhost:5432/test_database";
DatabaseDriverManager instance = DatabaseDriverManagerImpl.getInstance();
DatabaseDriver driver = instance.getDriver("postgresql");

ds = new LocalDataSource(); // note: the one using the password is deprecated
ds.setName("Test Data Source");
ds.setDatabaseDriver(driver);
ds.setUrl(testUrl);

@Nullable DbDataSource t = DbImplUtil.getDbDataSource(project, ds); // assuming the project is defined
if (t != null) {
OpenSourceUtil.navigate(true, true, t);
}

Hope it will be useful for some people.

( version 2020.2.2 )

1

Please sign in to leave a comment.