/**
   * Resolves the expression of an empty blob based on the configuration or if it is not available
   * in the configuration, based on the database type.
   *
   * @param configuration The configuration that was passed to the blobstore.
   * @return The expression of an empty blob that can be used in an insert statement.
   */
  protected Expression<Blob> resolveEmptyBlobExpression(
      final JdbcBlobstoreConfiguration configuration) {

    if (configuration != null && configuration.emptyBlobExpression != null) {
      return configuration.emptyBlobExpression;
    }

    DatabaseTypeEnum databaseType = guessDatabaseType();

    if (databaseType == DatabaseTypeEnum.ORACLE) {
      return SQLExpressions.relationalFunctionCall(Blob.class, "empty_blob");
    } else {
      return Expressions.constant(new EmptyReadOnlyBlob());
    }
  }
  /**
   * Resolving the selection expression of the blob based on the configuration or if it is not
   * available in the configuration, based on the database type. This is necessary as for example if
   * MySQL is used with remote locator mode, instead of the blob column name, a string constant has
   * to be used that contains the column name in the SQL expression.
   *
   * @param configuration The configuration passed to this blobstore.
   * @return The selection expression of the blob.
   */
  protected Expression<?> resolveBlobSelectionExpression(
      final JdbcBlobstoreConfiguration configuration) {

    if (configuration != null && configuration.blobSelectionExpression != null) {
      return configuration.blobSelectionExpression;
    }

    DatabaseTypeEnum databaseType = guessDatabaseType();
    if (databaseType != DatabaseTypeEnum.MYSQL) {
      return QBlobstoreBlob.blobstoreBlob.blob_;
    }

    try (Connection connection = dataSource.getConnection()) {
      if (!connection.getMetaData().locatorsUpdateCopy()) {
        return Expressions.constant(QBlobstoreBlob.blobstoreBlob.blob_.getMetadata().getName());
      } else {
        return QBlobstoreBlob.blobstoreBlob.blob_;
      }
    } catch (SQLException e) {
      // TODO Auto-generated catch block
      throw new RuntimeException(e);
    }
  }