commit 74767a05c4b0225c48d9fa25c3d9eebc6575e19e Author: lidongy <1879087903@qq.com> Date: Mon Jan 4 16:18:03 2021 +0800 PostgreSQL迁移插件 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..038c2a6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.iml +.idea/ +.DS_Store +.classpath +target/ +lib/report/*.jar \ No newline at end of file diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..dc5f815 --- /dev/null +++ b/build.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/finekit-10.0-20200630.jar b/lib/finekit-10.0-20200630.jar new file mode 100644 index 0000000..f4fbaf3 Binary files /dev/null and b/lib/finekit-10.0-20200630.jar differ diff --git a/lib/postgresql-42.1.4.jar b/lib/postgresql-42.1.4.jar new file mode 100644 index 0000000..08a54b1 Binary files /dev/null and b/lib/postgresql-42.1.4.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..a03f7ee --- /dev/null +++ b/plugin.xml @@ -0,0 +1,24 @@ + + + com.fr.plugin.migration.pgsql + + yes + no + 1.0.0 + 10.0 + 2020-11-18 + dec.lidongy + + [2020-11-18]第一版

+ ]]>
+ + + + + + + + + +
\ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e8c0293 --- /dev/null +++ b/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + com.fr.plugin + starter + 10.0 + + jar + decision-migration-pgsql + + + com.fanruan.api + finekit + 10.0 + system + ${project.basedir}/lib/finekit-10.0.jar + + + \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..742de8b --- /dev/null +++ b/readme.md @@ -0,0 +1,10 @@ +# PostgreSQL外置数据库迁移插件 + + +## 作用 + +将工程迁移至PostgreSQL外置数据库 + +## 插件使用简介 + +点击平台/系统管理,选择PostgreSQL,开始迁移 \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/migration/pgsql/FRPGSQLDialect.java b/src/main/java/com/fr/plugin/migration/pgsql/FRPGSQLDialect.java new file mode 100644 index 0000000..9cb1c05 --- /dev/null +++ b/src/main/java/com/fr/plugin/migration/pgsql/FRPGSQLDialect.java @@ -0,0 +1,20 @@ +package com.fr.plugin.migration.pgsql; + +import com.fr.third.org.hibernate.dialect.PostgresPlusDialect; + +import java.sql.Types; + +/** + * hibernate方言具体实现 + * + * @author lidongy + * @version 10.0 + * Created by lidongy on 2020/7/30 + */ +public class FRPGSQLDialect extends PostgresPlusDialect { + public FRPGSQLDialect() { + super(); + registerColumnType(Types.VARCHAR, 65536, "varchar($l)"); + registerColumnType(Types.VARCHAR, "text"); + } +} diff --git a/src/main/java/com/fr/plugin/migration/pgsql/PGSQLClassLoaderHandler.java b/src/main/java/com/fr/plugin/migration/pgsql/PGSQLClassLoaderHandler.java new file mode 100644 index 0000000..a3a9a67 --- /dev/null +++ b/src/main/java/com/fr/plugin/migration/pgsql/PGSQLClassLoaderHandler.java @@ -0,0 +1,26 @@ +package com.fr.plugin.migration.pgsql; + +import com.fanruan.api.log.LogKit; +import com.fr.stable.fun.impl.AbstractDataSourceDriverLoader; + +/** + * 迁移前,数据库测试连接处的过滤 + * + * @author lidongy + * @version 10.0 + * Created by lidongy on 2020/11/18 + */ +public class PGSQLClassLoaderHandler extends AbstractDataSourceDriverLoader { + public boolean isInterceptAllowed(String databaseType, String url) { + if (url.startsWith("jdbc:postgresql")) { + LogKit.info("[com.fr.plugin.connection.mysql8] The connection has been intercepted."); + return true; + } + return false; + } + + public ClassLoader getClassLoader() { + return this.getClass().getClassLoader(); + } + +} diff --git a/src/main/java/com/fr/plugin/migration/pgsql/PGSQLDialect.java b/src/main/java/com/fr/plugin/migration/pgsql/PGSQLDialect.java new file mode 100644 index 0000000..cb86b7d --- /dev/null +++ b/src/main/java/com/fr/plugin/migration/pgsql/PGSQLDialect.java @@ -0,0 +1,21 @@ +package com.fr.plugin.migration.pgsql; + +import com.fr.data.core.db.dialect.PostgreSQLDialect; +import com.fr.data.core.db.dialect.base.DialectKeyConstants; +import com.fr.data.core.db.dialect.base.key.hibernate.HibernateDialectClassExecutor; + + +/** + * 我们自己的方言框架(非hibernate)的实现,内部反射调用hibernate方言 + * + * @author lidongy + * @version 10.0 + * Created by lidongy on 2020/7/31 + */ +public class PGSQLDialect extends PostgreSQLDialect { + public PGSQLDialect() { + super(); + putExecutor(DialectKeyConstants.HIBERNATE_DIALECT_CLASS_KEY, new HibernateDialectClassExecutor(FRPGSQLDialect.class.getName())); + } +} + diff --git a/src/main/java/com/fr/plugin/migration/pgsql/PGSQLDialectCreator.java b/src/main/java/com/fr/plugin/migration/pgsql/PGSQLDialectCreator.java new file mode 100644 index 0000000..77d676b --- /dev/null +++ b/src/main/java/com/fr/plugin/migration/pgsql/PGSQLDialectCreator.java @@ -0,0 +1,42 @@ +package com.fr.plugin.migration.pgsql; + +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +import com.fr.intelli.record.Focus; +import com.fr.intelli.record.Original; +import com.fr.record.analyzer.EnableMetrics; +import com.fr.stable.UrlDriver; +import com.fr.stable.fun.impl.AbstractDialectCreator; + +import java.sql.Connection; + +/** + * 迁移时代码走到的的方言过滤 + * + * @author lidongy + * @version 10.0 + * Created by lidongy on 2020/7/31 + */ +@EnableMetrics +public class PGSQLDialectCreator extends AbstractDialectCreator { + @Override + @Focus(id = "com.fr.plugin.migration.pgsql", text = "", source = Original.PLUGIN) + public Class generate(UrlDriver urlDriver) { + if (StringKit.equals(urlDriver.getDriver(), "org.postgresql.Driver")) { + return PGSQLDialect.class; + } + return null; + } + + @Override + public Class generate(Connection connection) { + try { + if (connection.getMetaData().getURL().startsWith("jdbc:postgresql")) { + return PGSQLDialect.class; + } + } catch (Exception e) { + LogKit.error(e, e.getMessage()); + } + return null; + } +} diff --git a/src/main/java/com/fr/plugin/migration/pgsql/PGSQLLifecycleMonitor.java b/src/main/java/com/fr/plugin/migration/pgsql/PGSQLLifecycleMonitor.java new file mode 100644 index 0000000..369c184 --- /dev/null +++ b/src/main/java/com/fr/plugin/migration/pgsql/PGSQLLifecycleMonitor.java @@ -0,0 +1,69 @@ +package com.fr.plugin.migration.pgsql; + +import com.fanruan.api.util.GeneralKit; +import com.fanruan.api.util.IOKit; +import com.fr.config.FineDBDriverClassLoaderStore; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; +import com.fr.third.guava.io.ByteStreams; +import com.fr.workspace.WorkContext; + +import java.io.IOException; +import java.io.InputStream; + +/** + * 生命周期 + * + * @author lidongy + * @version 10.0 + * Created by lidongy on 2020/11/5 + */ +public class PGSQLLifecycleMonitor extends AbstractPluginLifecycleMonitor { + + @Override + public void afterRun(PluginContext pluginContext) { + //用配置项,而不放在afterInstall的原因:afterInstall的时候还读不到resource里的内容 + if (!PGSQLMigrationConfig.getInstance().isInit()) { + // 移动方言、jar包,防止重启后,外置数据库模块在插件模块之前启动,依赖不到方言和jar。 + // 此处不放在生命周期类afterInstall方法中的原因是要考虑 1,此插件有可能升级的情况 2,在afterInstall处读不到resource中的内容 + try { + moveDialectClass(); + moveDriverLib(); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); + } + PGSQLMigrationConfig.getInstance().setInit(true); + } + + // 产品内部逻辑实现是,注册之后的类加载器,在连接外置数据库时,都会传给druid。 + FineDBDriverClassLoaderStore.getInstance().add(this.getClass().getClassLoader()); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + FineDBDriverClassLoaderStore.getInstance().remove(this.getClass().getClassLoader()); + } + + @Override + public void beforeUninstall(PluginContext pluginContext) { + PGSQLMigrationConfig.getInstance().setInit(false); + } + + private void moveDialectClass() throws IOException { + InputStream is = IOKit.readResource("FRPGSQLDialect.class"); + String path = GeneralKit.pathJoin("/classes", FRPGSQLDialect.class.getName().replace('.', '/') + ".class"); + if (!WorkContext.getWorkResource().exist(path)) { + WorkContext.getWorkResource().write(path, ByteStreams.toByteArray(is)); + } + } + + private void moveDriverLib() throws IOException { + InputStream is = IOKit.readResource("postgresql-42.1.4.jar"); + String path = "/lib/postgresql-42.1.4.jar"; + if (!WorkContext.getWorkResource().exist(path)) { + WorkContext.getWorkResource().write(path, ByteStreams.toByteArray(is)); + } + } + +} diff --git a/src/main/java/com/fr/plugin/migration/pgsql/PGSQLMigrationConfig.java b/src/main/java/com/fr/plugin/migration/pgsql/PGSQLMigrationConfig.java new file mode 100644 index 0000000..23ecff9 --- /dev/null +++ b/src/main/java/com/fr/plugin/migration/pgsql/PGSQLMigrationConfig.java @@ -0,0 +1,35 @@ +package com.fr.plugin.migration.pgsql; + +import com.fr.config.ConfigContext; +import com.fr.config.DefaultConfiguration; +import com.fr.config.Identifier; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; + +/** + * @author lidongy + * @version 10.0 + * Created by lidongy on 2020/11/27 + */ +public class PGSQLMigrationConfig extends DefaultConfiguration { + + @Identifier(value = "init") + private Conf init = Holders.simple(false); + + private static volatile PGSQLMigrationConfig config = null; + + public static PGSQLMigrationConfig getInstance() { + if (config == null) { + config = ConfigContext.getConfigInstance(PGSQLMigrationConfig.class); + } + return config; + } + + public Boolean isInit() { + return init.get(); + } + + public void setInit(Boolean init) { + this.init.set(init); + } +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/migration/pgsql/web/PGSQLComponent.java b/src/main/java/com/fr/plugin/migration/pgsql/web/PGSQLComponent.java new file mode 100644 index 0000000..560ddcd --- /dev/null +++ b/src/main/java/com/fr/plugin/migration/pgsql/web/PGSQLComponent.java @@ -0,0 +1,20 @@ +package com.fr.plugin.migration.pgsql.web; + +import com.fr.web.struct.Component; +import com.fr.web.struct.browser.RequestClient; +import com.fr.web.struct.category.ScriptPath; + +/** + * @author lidongy + * @version 10.0 + * Created by lidongy on 2020/11/5 + */ +public class PGSQLComponent extends Component { + public static PGSQLComponent KEY = new PGSQLComponent(); + + @Override + public ScriptPath script(RequestClient req) { + return ScriptPath.build("com/fr/plugin/migration/pgsql/web/js/plugin.min.js"); + } + +} diff --git a/src/main/java/com/fr/plugin/migration/pgsql/web/PGSQLWebResource.java b/src/main/java/com/fr/plugin/migration/pgsql/web/PGSQLWebResource.java new file mode 100644 index 0000000..d1a3894 --- /dev/null +++ b/src/main/java/com/fr/plugin/migration/pgsql/web/PGSQLWebResource.java @@ -0,0 +1,22 @@ +package com.fr.plugin.migration.pgsql.web; + +import com.fr.decision.fun.impl.AbstractWebResourceProvider; +import com.fr.decision.web.MainComponent; +import com.fr.web.struct.Atom; + +/** + * @author lidongy + * @version 10.0 + * Created by lidongy on 2020/11/5 + */ +public class PGSQLWebResource extends AbstractWebResourceProvider { + @Override + public Atom attach() { + return MainComponent.KEY; + } + + @Override + public Atom client() { + return PGSQLComponent.KEY; + } +} \ No newline at end of file diff --git a/src/main/resources/FRPGSQLDialect.class b/src/main/resources/FRPGSQLDialect.class new file mode 100644 index 0000000..35bc819 Binary files /dev/null and b/src/main/resources/FRPGSQLDialect.class differ diff --git a/src/main/resources/com/fr/plugin/migration/pgsql/web/js/plugin.min.js b/src/main/resources/com/fr/plugin/migration/pgsql/web/js/plugin.min.js new file mode 100644 index 0000000..abe6899 --- /dev/null +++ b/src/main/resources/com/fr/plugin/migration/pgsql/web/js/plugin.min.js @@ -0,0 +1,22 @@ +!(function () { + BI.config('dec.provider.migration', provider => { + provider.registerDatabase({ + value: 'postgresql', + driver: ['org.postgresql.Driver'], + url: 'jdbc:postgresql://{host}:{port}/{database}', + schema: true, + port: 5432, + }, url => { + const result = url.match(/^jdbc:postgresql:\/\/([0-9a-zA-Z_\\.-]+)(:([0-9]+))?\/([0-9a-zA-Z_\\.]+)(.*)/i); + + if (result) { + return { + host: result[1], + port: result[3], + databaseName: result[4], + urlInfo: result[5], + }; + } + }); + }); +}()); diff --git a/src/main/resources/postgresql-42.1.4.jar b/src/main/resources/postgresql-42.1.4.jar new file mode 100644 index 0000000..08a54b1 Binary files /dev/null and b/src/main/resources/postgresql-42.1.4.jar differ