/** Construct with a naming convention and platform specific DDL. */
 public BaseTableDdl(ServerConfig serverConfig, PlatformDdl platformDdl) {
   this.namingConvention = serverConfig.getNamingConvention();
   this.naming = serverConfig.getConstraintNaming();
   this.historyTableSuffix = serverConfig.getHistoryTableSuffix();
   this.platformDdl = platformDdl;
   this.platformDdl.configure(serverConfig);
 }
  /** Set the naming convention to underscore if it has not already been set. */
  private void setNamingConvention(ServerConfig config) {
    if (config.getNamingConvention() == null) {
      UnderscoreNamingConvention nc = new UnderscoreNamingConvention();
      config.setNamingConvention(nc);

      String v = config.getProperty("namingConvention.useForeignKeyPrefix");
      if (v != null) {
        boolean useForeignKeyPrefix = Boolean.valueOf(v);
        nc.setUseForeignKeyPrefix(useForeignKeyPrefix);
      }

      String sequenceFormat = config.getProperty("namingConvention.sequenceFormat");
      if (sequenceFormat != null) {
        nc.setSequenceFormat(sequenceFormat);
      }
    }
  }
  /** Create the implementation from the configuration. */
  public SpiEbeanServer createServer(ServerConfig serverConfig) {

    synchronized (this) {
      setNamingConvention(serverConfig);

      BootupClasses bootupClasses = getBootupClasses(serverConfig);

      setDataSource(serverConfig);
      // check the autoCommit and Transaction Isolation
      boolean online = checkDataSource(serverConfig);

      // determine database platform (Oracle etc)
      setDatabasePlatform(serverConfig);
      if (serverConfig.getDbEncrypt() != null) {
        // use a configured DbEncrypt rather than the platform default
        serverConfig.getDatabasePlatform().setDbEncrypt(serverConfig.getDbEncrypt());
      }

      DatabasePlatform dbPlatform = serverConfig.getDatabasePlatform();

      PstmtBatch pstmtBatch = null;

      if (dbPlatform.getName().startsWith("oracle")) {
        PstmtDelegate pstmtDelegate = serverConfig.getPstmtDelegate();
        if (pstmtDelegate == null) {
          // try to provide the
          pstmtDelegate = getOraclePstmtDelegate(serverConfig.getDataSource());
        }
        if (pstmtDelegate != null) {
          // We can support JDBC batching with Oracle
          // via OraclePreparedStatement
          pstmtBatch = new OraclePstmtBatch(pstmtDelegate);
        }
        if (pstmtBatch == null) {
          // We can not support JDBC batching with Oracle
          logger.warning("Can not support JDBC batching with Oracle without a PstmtDelegate");
          serverConfig.setPersistBatching(false);
        }
      }

      // inform the NamingConvention of the associated DatabasePlaform
      serverConfig.getNamingConvention().setDatabasePlatform(serverConfig.getDatabasePlatform());

      ServerCacheManager cacheManager = getCacheManager(serverConfig);

      int uniqueServerId = serverId.incrementAndGet();
      SpiBackgroundExecutor bgExecutor = createBackgroundExecutor(serverConfig, uniqueServerId);

      InternalConfiguration c =
          new InternalConfiguration(
              xmlConfig,
              clusterManager,
              cacheManager,
              bgExecutor,
              serverConfig,
              bootupClasses,
              pstmtBatch);

      DefaultServer server = new DefaultServer(c, cacheManager);

      cacheManager.init(server);

      MBeanServer mbeanServer;
      ArrayList<?> list = MBeanServerFactory.findMBeanServer(null);
      if (list.size() == 0) {
        // probably not running in a server
        mbeanServer = MBeanServerFactory.createMBeanServer();
      } else {
        // use the first MBeanServer
        mbeanServer = (MBeanServer) list.get(0);
      }

      server.registerMBeans(mbeanServer, uniqueServerId);

      // generate and run DDL if required
      executeDDL(server, online);

      // initialise prior to registering with clusterManager
      server.initialise();

      if (online) {
        if (clusterManager.isClustering()) {
          // register the server once it has been created
          clusterManager.registerServer(server);
        }

        // warm the cache in 30 seconds
        int delaySecs = GlobalProperties.getInt("ebean.cacheWarmingDelay", 30);
        long sleepMillis = 1000 * delaySecs;

        if (sleepMillis > 0) {
          Timer t = new Timer("EbeanCacheWarmer", true);
          t.schedule(new CacheWarmer(server), sleepMillis);
        }
      }

      // start any services after registering with clusterManager
      server.start();
      return server;
    }
  }