diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/annotation/PreLoad.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/annotation/PreLoad.java new file mode 100644 index 00000000..f6961304 --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/annotation/PreLoad.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * @author: aoshiguchen + * @date: 2022/7/31 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface PreLoad { + String value() default "preLoad"; +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/AbstractBeanFactory.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/AbstractBeanFactory.java index 84b8fcfe..5951aa92 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/AbstractBeanFactory.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/bean/AbstractBeanFactory.java @@ -29,6 +29,7 @@ import fun.asgc.neutrino.core.exception.BeanException; import fun.asgc.neutrino.core.util.*; import lombok.extern.slf4j.Slf4j; +import java.util.Comparator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -544,7 +545,8 @@ public abstract class AbstractBeanFactory implements BeanFactory, BeanRegistry, * 运行 */ private void run() { - beanCache.values().stream().filter(b -> b.getStatus().getStatus() < BeanStatus.RUNNING.getStatus()).forEach(b -> { + beanCache.values().stream().filter(b -> b.getStatus().getStatus() < BeanStatus.RUNNING.getStatus()) + .sorted(Comparator.comparing(BeanWrapper::getOrder)).forEach(b -> { try { getOrNew(b); b.run(getEnvironment().getMainArgs()); diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/context/ApplicationContext.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/context/ApplicationContext.java index 68b36880..12a0d3d7 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/context/ApplicationContext.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/context/ApplicationContext.java @@ -22,6 +22,7 @@ package fun.asgc.neutrino.core.context; +import fun.asgc.neutrino.core.annotation.PreLoad; import fun.asgc.neutrino.core.base.GlobalConfig; import fun.asgc.neutrino.core.bean.BeanFactoryAware; import fun.asgc.neutrino.core.bean.SimpleBeanFactory; @@ -31,8 +32,11 @@ import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; import java.io.IOException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; /** @@ -61,7 +65,7 @@ public class ApplicationContext implements LifeCycle { * 生命周期管理者 */ private LifeCycleManager lifeCycleManager = LifeCycleManager.create(); - + private Set> classes = new HashSet<>(); public ApplicationContext(Environment environment) { this.environment = environment; @@ -72,11 +76,13 @@ public class ApplicationContext implements LifeCycle { this.lifeCycleManager.init(() -> { try { GlobalConfig.setIsContainerStartup(true); + this.classes = ClassUtil.scan(environment.getScanBasePackages()); this.rootBeanFactory = new SimpleBeanFactory("rootBeanFactory"); this.applicationBeanFactory = new SimpleBeanFactory(rootBeanFactory, "applicationBeanFactory"); this.rootBeanFactory.registerBean(environment); this.rootBeanFactory.registerBean(this); this.rootBeanFactory.registerBean(environment.getConfig()); + preLoad(); register(); List beanFactoryAwareList = this.applicationBeanFactory.getBeanList(BeanFactoryAware.class); if (CollectionUtil.notEmpty(beanFactoryAwareList)) { @@ -95,21 +101,52 @@ public class ApplicationContext implements LifeCycle { @Override public void destroy() { this.lifeCycleManager.destroy(() -> { - this.applicationBeanFactory.destroy(); log.info("应用上下文销毁"); }); } + /** + * 预加载 + * @throws Exception + */ + private void preLoad() throws Exception { + for (Class c : this.classes) { + if (!c.isAnnotationPresent(PreLoad.class)) { + continue; + } + Set methodSet = ReflectUtil.getDeclaredMethods(c); + if (CollectionUtil.isEmpty(methodSet)) { + continue; + } + PreLoad preLoad = c.getAnnotation(PreLoad.class); + String name = preLoad.value(); + if (StringUtil.isEmpty(name)) { + continue; + } + Optional methodOptional = methodSet.stream().filter(m -> m.getName().equals(name) && Modifier.isStatic(m.getModifiers()) + && (m.getParameterCount() == 0 || + (m.getParameterCount() == 1 && m.getParameters()[0].getType().isArray() && String.class.isAssignableFrom(m.getParameters()[0].getType().getComponentType())))) + .findFirst(); + if (!methodOptional.isPresent()) { + continue; + } + Method method = methodOptional.get(); + Object o = c.newInstance(); + log.debug("PreLoad execute {}#{}", c.getName(), method.getName()); + if (method.getParameterCount() == 0) { + method.invoke(o); + } else { + method.invoke(o, new Object[]{this.environment.getMainArgs()}); + } + } + } + /** * bean注册 * 所有的拦截器默认都是bean组件,没带Component注解时,默认是延迟加载的 */ private void register() throws IOException, ClassNotFoundException { - Set> classes = ClassUtil.scan(environment.getScanBasePackages()); - if (null == classes) { - classes = new HashSet<>(); - } classes.add(BeanManager.class); classes.add(ExtensionServiceLoader.class); applicationBeanFactory.register(classes); @@ -120,9 +157,5 @@ public class ApplicationContext implements LifeCycle { */ public void run() { init(); -// List applicationRunnerList = this.applicationBeanFactory.getBeanList(ApplicationRunner.class); -// if (CollectionUtil.notEmpty(applicationRunnerList)) { -// applicationRunnerList.forEach(applicationRunner -> applicationRunner.run(this.environment.getMainArgs())); -// } } } diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/FileUtil.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/FileUtil.java index 772e3cfe..f221ef07 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/FileUtil.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/FileUtil.java @@ -33,6 +33,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Enumeration; +import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.stream.Collectors; @@ -89,6 +90,20 @@ public class FileUtil { } } + /** + * 读取文件内容 + * @param path + * @return + * @throws IOException + */ + public static List readContentAsStringList(String path) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(getInputStream(path)))){ + return br.lines().collect(Collectors.toList()); + } catch (Exception e) { + return null; + } + } + /** * 读取字节内容 * @param path diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/Launcher.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/Launcher.java new file mode 100644 index 00000000..cd9771f6 --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/Launcher.java @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.core.bean.test5; + +import fun.asgc.neutrino.core.annotation.NeutrinoApplication; +import fun.asgc.neutrino.core.context.NeutrinoLauncher; + +/** + * + * @author: aoshiguchen + * @date: 2022/7/31 + */ +@NeutrinoApplication +public class Launcher { + + public static void main(String[] args) { + NeutrinoLauncher.run(Launcher.class, args); + } + +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/PreLoad1.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/PreLoad1.java new file mode 100644 index 00000000..5569489d --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/PreLoad1.java @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.core.bean.test5; + +import fun.asgc.neutrino.core.annotation.PreLoad; + +/** + * + * @author: aoshiguchen + * @date: 2022/7/31 + */ +@PreLoad +public class PreLoad1 { + + public static void preLoad(String[] args) { + System.out.println("11"); + } + +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/Runner1.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/Runner1.java new file mode 100644 index 00000000..9f88a9e1 --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/Runner1.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.core.bean.test5; + +import fun.asgc.neutrino.core.annotation.Component; +import fun.asgc.neutrino.core.annotation.Order; +import fun.asgc.neutrino.core.context.ApplicationRunner; + +/** + * + * @author: aoshiguchen + * @date: 2022/7/31 + */ +@Order(0) +@Component +public class Runner1 implements ApplicationRunner { + + @Override + public void run(String[] args) throws Exception { + System.out.println("1111"); + try { + Thread.sleep(3000); + } catch (Exception e) { + // + } + System.out.println("----11111"); + } +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/Runner2.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/Runner2.java new file mode 100644 index 00000000..54d22127 --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/bean/test5/Runner2.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.core.bean.test5; + +import fun.asgc.neutrino.core.annotation.Component; +import fun.asgc.neutrino.core.annotation.Order; +import fun.asgc.neutrino.core.context.ApplicationRunner; + +/** + * + * @author: aoshiguchen + * @date: 2022/7/31 + */ +@Order(1) +@Component +public class Runner2 implements ApplicationRunner { + + @Override + public void run(String[] args) throws Exception { + System.out.println("2222"); + } +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/db/template/JdbcTemplateTestForSqlite2.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/db/template/JdbcTemplateTestForSqlite2.java new file mode 100644 index 00000000..e52d76d5 --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/db/template/JdbcTemplateTestForSqlite2.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.core.db.template; + +import org.junit.Test; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +/** + * + * @author: aoshiguchen + * @date: 2022/7/31 + */ +public class JdbcTemplateTestForSqlite2 { + @Test + public void test1() throws ClassNotFoundException, SQLException { + Class.forName("org.sqlite.JDBC"); + //建立一个数据库名zieckey.db的连接,如果不存在就在当前目录下创建之 + Connection conn = DriverManager.getConnection("jdbc:sqlite:aa.db"); + System.out.println(conn); + } +} diff --git a/neutrino-core/src/test/resources/application.yml b/neutrino-core/src/test/resources/application.yml index 8b4c35e4..7123ece4 100644 --- a/neutrino-core/src/test/resources/application.yml +++ b/neutrino-core/src/test/resources/application.yml @@ -2,7 +2,7 @@ neutrino: application: name: neutrino-proxy-server http: - enable: true + enable: false port: 8080 context-path: /test max-content-length-desc: 128K diff --git a/neutrino-proxy-server/pom.xml b/neutrino-proxy-server/pom.xml index 41190616..b168a2a8 100644 --- a/neutrino-proxy-server/pom.xml +++ b/neutrino-proxy-server/pom.xml @@ -20,6 +20,11 @@ neutrino-proxy-core ${revision} + + org.xerial + sqlite-jdbc + 3.7.2 + diff --git a/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/DBInitialize.java b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/DBInitialize.java new file mode 100644 index 00000000..a2a37725 --- /dev/null +++ b/neutrino-proxy-server/src/main/java/fun/asgc/neutrino/proxy/server/base/rest/DBInitialize.java @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package fun.asgc.neutrino.proxy.server.base.rest; + +import fun.asgc.neutrino.core.annotation.PreLoad; +import fun.asgc.neutrino.core.util.CollectionUtil; +import fun.asgc.neutrino.core.util.FileUtil; +import fun.asgc.neutrino.core.util.LockUtil; +import fun.asgc.neutrino.core.util.StringUtil; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; +import java.util.List; + +/** + * + * @author: 初始化数据库 + * @date: 2022/7/31 + */ +@PreLoad("init") +public class DBInitialize { + + private static Connection conn; + + public static void init() throws Exception { + initDBStructure(); + } + + /** + * 初始化数据库结构 + */ + private static void initDBStructure() throws Exception { + Statement stat = getOrNewConnection().createStatement(); + List lines = FileUtil.readContentAsStringList("classpath:/init-structure.sql"); + if (CollectionUtil.isEmpty(lines)) { + return; + } + String sql = ""; + for (String line : lines) { + if (StringUtil.isEmpty(line) || StringUtil.isEmpty(line.trim()) || line.trim().startsWith("#")) { + continue; + } + sql += "\r\n" + line.trim(); + if (sql.endsWith(";")) { + stat.executeUpdate(sql); + sql = ""; + } + } + } + + /** + * 获取一个数据库连接,如果数据库不存在,则会创建一个空数据库 + * @return + * @throws Exception + */ + public static Connection getOrNewConnection() throws Exception { + return LockUtil.doubleCheckProcess( + () -> null == conn, + DBInitialize.class, + () -> { + Class.forName("org.sqlite.JDBC"); + //建立一个数据库名data.db的连接,如果不存在就在当前目录下创建之 + DBInitialize.conn = DriverManager.getConnection("jdbc:sqlite:data.db"); + }, + () -> conn + ); + } +} diff --git a/neutrino-proxy-server/src/main/resources/init-structure.sql b/neutrino-proxy-server/src/main/resources/init-structure.sql new file mode 100644 index 00000000..ae55d842 --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/init-structure.sql @@ -0,0 +1,19 @@ +#用户表 +CREATE TABLE IF NOT EXISTS `user` ( + `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + `name` varchar(50) NOT NULL, + `login_name` varchar(50) NOT NULL, + `login_password` varchar(255) NOT NULL, + `create_time` INTEGER(20) NOT NULL, + `update_time` INTEGER(20) NOT NULL +); + +#license表 +CREATE TABLE IF NOT EXISTS `license` ( + `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + `name` varchar(50) NOT NULL, + `key` varchar(100) NOT NULL, + `user_id` INTEGER NOT NULL, + `create_time` INTEGER(20) NOT NULL, + `update_time` INTEGER(20) NOT NULL +);