Support for MariaDB: Looking for volunteers

This is really cool, I hope this will help when attempting to do the same thing with Postgresql. Is Postgresql by any chance in your scope as well?

Not in scope. But I’m pretty sure PostgreSQL also has a JDBC driver, so steps could be repeated.

Good luck

FYI we are running UI tests against Reference Application on both MySQL and MariaDB, see https://travis-ci.org/openmrs/openmrs-distro-referenceapplication/

Interestingly in tests we use MySQL driver to connect to MariaDB. However, we do not install RA from scratch rather upgrade from platform 1.9.x. I do think using MariaDB driver should be preferred, but I am curious what issues you experienced using MySQL driver? It seems our tests do not cover your case.

1 Like

@aloginov, would you be willing to file a ticket for this a create a pull request?

It looks like mariadb is missing from DatabaseUtil.loadDatabaseDriver(…) as well.

Would it be overkill to adopt the strategy pattern for database-specific features – i.e., create an interface enumerating the database-specific tasks needed from OpenMRS and then implement that interface for each supported database (to avoid a growing stack of if…else that is repeated in multiple places)?

Anyway, let’s not let perfect be the enemy of the good. If you could create a TRUNK ticket for your change and throw in a pull request, we’d appreciate it (as would the next person using mariadb)! :slight_smile:

Thanks ALOT for this work , Am also trying to replace the embedded mysql database with mariaDB4J but according to the @aloginov description, it seems

To: if (wizardModel.databaseConnection.contains(“mysql”)) { Class.forName(“com.mysql.jdbc.Driver”).newInstance(); } else if (wizardModel.databaseConnection.contains(“mariadb”)) { Class.forName(“org.mariadb.jdbc.Driver”).newInstance(); } else { replacedSql = replacedSql.replaceAll(“`”, “”"); }

It seems this is the same creteria i need to figure out from, am working with @ibacher,@dkayiwa about this however am would like to hear from your views thanks

That seems like it would work, but as @burke said, there’s probably a better way to do it. In particular, I actually think constructions like this:

if (isCurrentDatabase(DATABASE_MYSQL)) {
	Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
} else if (isCurrentDatabase(DATABASE_POSTGRESQL)) {
	Class.forName("org.postgresql.Driver").newInstance();
	replacedSql = replacedSql.replaceAll("`", "\"");
} else {
	replacedSql = replacedSql.replaceAll("`", "\"");
}

are outdated.

DriverManager can use the Java Service Provider mechanism to already identify the correct driver given a database URL, as long as it’s on the classpath, and this has been implemented in all of MySQL Connector / J 5.x, the PostgreSQL JDBC connector and MariaDB.

This means we should just be able to do this:

DriverManager.getConnection(url, user, password);

and get a valid database connection without all the Class.forName() calls.

That said, we’d still need to differentiate between how to generate the right format for certain queries…

Thanks alot for your clarification, i agree with you for us not going deep in postgreSQL at this time

Using something like this?

String dbName = connection.getMetadata().getDatabaseProductName();
switch(dbName.toUpperCase()) {
  case "MARIADB":
    // do the mariadb thing
  case "POSTGRES"
    // do the postgres thing
  default:
    // do the mysql thing
}
1 Like

Yes, but I’d imagine this is actually a good place for the strategy pattern you were recommending above since there are a range of queries that need to be determined on a per-database thing :slight_smile:. I also suspect the MariaDB and MySQL implementations would be largely identical.

1 Like

Thanks @ibacher @burke this is how i tried to implement it, ticket, the problem is that, mysql.exe gets stopped i cant tell why this happens which breaks script the setup-openmrs-user.sql from being executed