From 9ed33299fd0c93637a93e9adaa6b297bef57393e Mon Sep 17 00:00:00 2001 From: XiaoLFeng Date: Sat, 23 Dec 2023 16:47:47 +0800 Subject: [PATCH] Initial commit --- .gitignore | 38 +++++ .idea/.gitignore | 8 + .idea/dataSources.xml | 17 ++ .idea/encodings.xml | 7 + .idea/kotlinc.xml | 6 + .idea/misc.xml | 15 ++ .idea/sqldialects.xml | 6 + .idea/uiDesigner.xml | 124 ++++++++++++++ .idea/vcs.xml | 6 + config.json | 6 + pom.xml | 99 +++++++++++ src/main/kotlin/com/xlf/lwtm/Data.kt | 7 + src/main/kotlin/com/xlf/lwtm/Database.kt | 194 ++++++++++++++++++++++ src/main/kotlin/com/xlf/lwtm/FileCheck.kt | 78 +++++++++ src/main/kotlin/com/xlf/lwtm/Main.kt | 45 +++++ xf_blog_waline.sql | 148 +++++++++++++++++ 16 files changed, 804 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/dataSources.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/kotlinc.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/sqldialects.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/vcs.xml create mode 100644 config.json create mode 100644 pom.xml create mode 100644 src/main/kotlin/com/xlf/lwtm/Data.kt create mode 100644 src/main/kotlin/com/xlf/lwtm/Database.kt create mode 100644 src/main/kotlin/com/xlf/lwtm/FileCheck.kt create mode 100644 src/main/kotlin/com/xlf/lwtm/Main.kt create mode 100755 xf_blog_waline.sql diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..dff2e22 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,17 @@ + + + + + mysql.8 + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://localhost:3306/waline + + + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..942f3a2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..ae3f30a --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5d6b03c --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml new file mode 100644 index 0000000..56782ca --- /dev/null +++ b/.idea/sqldialects.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/config.json b/config.json new file mode 100644 index 0000000..dfbdaf0 --- /dev/null +++ b/config.json @@ -0,0 +1,6 @@ +{ + "mysql_url": "127.0.0.1:3306", + "mysql_user": "waline", + "mysql_password": "123456", + "mysql_database": "waline" +} \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..16e4af4 --- /dev/null +++ b/pom.xml @@ -0,0 +1,99 @@ + + + 4.0.0 + + com.xlf + lwtm + 1.0-SNAPSHOT + + + + UTF-8 + official + 1.8 + + + + + mavenCentral + https://repo1.maven.org/maven2/ + + + + + src/main/kotlin + src/test/kotlin + + + org.jetbrains.kotlin + kotlin-maven-plugin + 1.9.21 + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + + maven-surefire-plugin + 2.22.2 + + + maven-failsafe-plugin + 2.22.2 + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + com.xlf.lwtm.MainKtKt + + + + + + + + org.jetbrains.kotlin + kotlin-test-junit5 + 1.9.21 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.10.0 + test + + + org.jetbrains.kotlin + kotlin-stdlib + 1.9.21 + + + com.google.code.gson + gson + 2.10.1 + + + mysql + mysql-connector-java + 8.0.33 + + + + \ No newline at end of file diff --git a/src/main/kotlin/com/xlf/lwtm/Data.kt b/src/main/kotlin/com/xlf/lwtm/Data.kt new file mode 100644 index 0000000..8fb0ee7 --- /dev/null +++ b/src/main/kotlin/com/xlf/lwtm/Data.kt @@ -0,0 +1,7 @@ +package com.xlf.lwtm + +object Data { + val commentJson = ArrayList>() + val counterJson = ArrayList>() + val usersJson = ArrayList>() +} diff --git a/src/main/kotlin/com/xlf/lwtm/Database.kt b/src/main/kotlin/com/xlf/lwtm/Database.kt new file mode 100644 index 0000000..f24dfdb --- /dev/null +++ b/src/main/kotlin/com/xlf/lwtm/Database.kt @@ -0,0 +1,194 @@ +package com.xlf.lwtm + +import com.google.gson.Gson +import com.google.gson.internal.LinkedTreeMap +import java.io.File +import java.sql.* +import java.time.Instant +import kotlin.system.exitProcess + +class Database { + private var connection: Connection? = null + + fun checkConnect() { + val connectInfo = + Gson().fromJson(File("config.json").readText(), HashMap::class.java) as HashMap + + try { + Class.forName("com.mysql.cj.jdbc.Driver") + connection = DriverManager.getConnection( + "jdbc:mysql://${connectInfo["mysql_url"]}/${connectInfo["mysql_database"]}", + connectInfo["mysql_user"], + connectInfo["mysql_password"] + ) + } catch (e: Exception) { + println("[ERROR] 数据库连接失败") + println("[ERROR] ${e.message}") + exitProcess(0) + } + } + + fun insertUsers(): Boolean { + Data.usersJson.forEach { hashMap -> + try { + connection!!.prepareStatement("INSERT INTO wl_users (display_name, email, password, type, label, url, avatar, github, twitter, facebook, google, weibo, qq, `2fa`, createdAt, updatedAt, user_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + .also { it.setString(1, hashMap["display_name"] as String?) } + .also { it.setString(2, hashMap["email"] as String) } + .also { it.setString(3, hashMap["password"] as String) } + .also { it.setString(4, hashMap["type"] as String) } + .also { it.setString(5, hashMap["label"] as String?) } + .also { it.setString(6, hashMap["url"] as String?) } + .also { it.setString(7, hashMap["avatar"] as String?) } + .also { it.setString(8, hashMap["github"] as String?) } + .also { it.setString(9, hashMap["twitter"] as String?) } + .also { it.setString(10, hashMap["facebook"] as String?) } + .also { it.setString(11, hashMap["google"] as String?) } + .also { it.setString(12, hashMap["weibo"] as String?) } + .also { it.setString(13, hashMap["qq"] as String?) } + .also { it.setString(14, hashMap["2fa"] as String?) }.also { + it.setTimestamp( + 15, Timestamp(Instant.parse(hashMap["createdAt"] as String).toEpochMilli()) + ) + }.also { + it.setTimestamp( + 16, Timestamp(Instant.parse(hashMap["updatedAt"] as String).toEpochMilli()) + ) + }.also { it.setString(17, hashMap["objectId"] as String?) }.executeUpdate() + } catch (e: Exception) { + println("[ERROR] 数据库插入失败") + println("[ERROR] ${e.message}") + throw e + } + } + return true + } + + fun insertCounter() { + Data.counterJson.forEach { hashMap -> + connection!!.prepareStatement("INSERT INTO wl_counter (time, reaction0, reaction1, reaction2, reaction3, reaction4, reaction5, reaction6, reaction7, reaction8, url, createdAt, updatedAt) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)") + .also { it.setString(1, hashMap["key"] as String) }.also { it.setInt(2, hashMap["value"] as Int) } + .executeUpdate() + } + } + + fun insertComment(): Boolean { + Data.commentJson.forEach { hashMap -> + try { + connection!!.prepareStatement("INSERT INTO wl_comment (user_id, comment, insertedAt, ip, link, mail, nick, pid, rid, sticky, status, `like`, ua, url, createdAt, updatedAt, object_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + .also { data -> + if (hashMap["user_id"] == null) { + data.setNull(1, Types.INTEGER) + } else { + val getData = + connection!!.prepareStatement("SELECT id, user_id FROM wl_users WHERE user_id = ?") + .also { it.setString(1, hashMap["user_id"] as String) }.executeQuery() + .also { it.next() } + if (getData.getString("user_id") == hashMap["user_id"]) { + data.setInt(1, getData.getInt("id")) + } + } + }.also { + if (hashMap["comment"] == null) { + it.setNull(2, Types.VARCHAR) + } else { + it.setString(2, hashMap["comment"] as String) + } + }.also { + val insertAt = hashMap["insertedAt"] as LinkedTreeMap<*, *> + it.setTimestamp( + 3, Timestamp(Instant.parse(insertAt["iso"] as String).toEpochMilli()) + ) + }.also { it.setString(4, hashMap["ip"] as String) }.also { + if (hashMap["link"] == null) { + it.setNull(5, Types.VARCHAR) + } else { + it.setString(5, hashMap["link"] as String) + } + }.also { + if (hashMap["mail"] == null) { + it.setNull(6, Types.VARCHAR) + } else { + it.setString(6, hashMap["mail"] as String) + } + }.also { + if (hashMap["nick"] == null) { + it.setNull(7, Types.VARCHAR) + } else { + it.setString(7, hashMap["nick"] as String) + } + }.also { comment -> + // 回复相关 + if (hashMap["pid"] == null) { + comment.setNull(8, Types.INTEGER) + } else { + val getData = + connection!!.prepareStatement("SELECT id, object_id FROM wl_comment WHERE object_id = ?") + .also { it.setString(1, hashMap["pid"] as String) }.executeQuery() + .also { it.next() } + try { + if ((getData.getString("object_id") ?: null) == hashMap["pid"]) { + comment.setInt(8, getData.getInt("id")) + } + } catch (e: SQLException) { + comment.setNull(8, Types.INTEGER) + } + } + }.also { comment -> + // 回复相关 + if (hashMap["rid"] == null) { + comment.setNull(9, Types.INTEGER) + } else { + val getData = + connection!!.prepareStatement("SELECT id, object_id FROM wl_comment WHERE object_id = ?") + .also { it.setString(1, hashMap["rid"] as String) }.executeQuery() + .also { it.next() } + try { + if ((getData.getString("object_id") ?: null) == hashMap["rid"]) { + comment.setInt(9, getData.getInt("id")) + } + } catch (e: SQLException) { + comment.setNull(9, Types.INTEGER) + } + } + }.also { + if (hashMap["sticky"] == null) { + it.setNull(10, Types.INTEGER) + } else { + it.setInt(10, hashMap["sticky"] as Int) + } + }.also { it.setString(11, hashMap["status"] as String) }.also { + if (hashMap["like"] == null) { + it.setNull(12, Types.INTEGER) + } else { + it.setInt(12, (hashMap["like"] as Double).toInt()) + } + }.also { + if (hashMap["ua"] == null) { + it.setNull(13, Types.VARCHAR) + } else { + it.setString(13, hashMap["ua"] as String) + } + }.also { + if (hashMap["url"] == null) { + it.setNull(14, Types.VARCHAR) + } else { + it.setString(14, hashMap["url"] as String) + } + }.also { + it.setTimestamp( + 15, Timestamp(Instant.parse(hashMap["createdAt"] as String).toEpochMilli()) + ) + }.also { + it.setTimestamp( + 16, Timestamp(Instant.parse(hashMap["updatedAt"] as String).toEpochMilli()) + ) + }.also { it.setString(17, hashMap["objectId"] as String) }.executeUpdate() + } catch (e: Exception) { + println("[ERROR] 数据库插入失败") + println("[ERROR] ${e.message}") + throw e + } + } + return true + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/xlf/lwtm/FileCheck.kt b/src/main/kotlin/com/xlf/lwtm/FileCheck.kt new file mode 100644 index 0000000..29f8f43 --- /dev/null +++ b/src/main/kotlin/com/xlf/lwtm/FileCheck.kt @@ -0,0 +1,78 @@ +package com.xlf.lwtm + +import com.google.gson.Gson +import java.io.File + +object FileCheck { + private val getCommentFile = File("Comment.0.jsonl") + private val getCounterFile = File("Counter.0.jsonl") + private val getUsersFile = File("Users.0.jsonl") + + fun check(): Boolean { + println("[INFO] 对文件进行检查") + // 查找 Comment.0.jsonl 文件 + if (!getCommentFile.exists() && !getCommentFile.isFile) { + println("\t[ERROR] 未找到 Comment.0.jsonl 文件") + return false + } else { + println("\t[CHECK] 找到 Comment.0.jsonl 文件") + } + // 查找 Counter.0.jsonl 文件 + if (!getCounterFile.exists() && !getCounterFile.isFile) { + println("\t[ERROR] 未找到 Counter.0.jsonl 文件") + return false + } else { + println("\t[CHECK] 找到 Counter.0.jsonl 文件") + } + // 查找 Users.0.jsonl 文件 + if (!getUsersFile.exists() && !getUsersFile.isFile) { + println("\t[ERROR] 未找到 Users.0.jsonl 文件") + return false + } else { + println("\t[CHECK] 找到 Users.0.jsonl 文件") + } + return true + } + + fun verify(): Boolean { + println("[INFO] 对文件进行校验") + // 获取文件并对 json 内容序列化 + try { + val getCommentFile = getCommentFile.readLines() + val getCounterFile = getCounterFile.readLines() + val getUsersFile = getUsersFile.readLines() + // 判断是否为空 + if (getCommentFile.isEmpty()) { + println("\t[ERROR] 文件内容为空") + return false + } + if (getCounterFile.isEmpty()) { + println("\t[ERROR] 文件内容为空") + return false + } + if (getUsersFile.isEmpty()) { + println("\t[ERROR] 文件内容为空") + return false + } + // 获取文件内容 json 序列化数组存储 + try { + getCommentFile.forEach { + Data.commentJson.add(Gson().fromJson(it, HashMap::class.java) as HashMap) + } + getCounterFile.forEach { + Data.counterJson.add(Gson().fromJson(it, HashMap::class.java) as HashMap) + } + getUsersFile.forEach { + Data.usersJson.add(Gson().fromJson(it, HashMap::class.java) as HashMap) + } + } catch (e: Exception) { + println("\t[ERROR] 文件内容不是 json 格式") + return false + } + } catch (e: Exception) { + println("\t[ERROR] 文件读取错误") + return false + } + return true + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/xlf/lwtm/Main.kt b/src/main/kotlin/com/xlf/lwtm/Main.kt new file mode 100644 index 0000000..eef331b --- /dev/null +++ b/src/main/kotlin/com/xlf/lwtm/Main.kt @@ -0,0 +1,45 @@ +package com.xlf.lwtm + +fun main() { + println("========================================") + println(" Waline LeanCloud Converter") + println(" LeanCloud To Mysql") + println(" 筱锋xiao_lfeng") + println(" V1.0.0") + println("========================================") + print("\n\n") + println("[INFO] 请将 Comment.0.jsonl、Counter.0.jsonl、Users.0.jsonl 文件放置在本程序同目录下") + println("[INFO] 确认是否进行转换(转换过程中请勿关闭程序)") + print("\t(1.确认; 2.取消):") + // 判断是否开始 + val input = readlnOrNull() + if (input != null && input == "1") { + // 文件检查 + if (FileCheck.check()) { + println("[SUCCESS] 文件检查成功") + } else { + return + } + // 文件校验 + if (FileCheck.verify()) { + println("[SUCCESS] 文件校验成功") + } else { + return + } + + // 数据库连接检查 + val database = Database() + database.checkConnect() + if (database.insertUsers()) { + println("[SUCCESS] 用户数据导入成功") + } else { + return + } + if (database.insertComment()) { + println("[SUCCESS] 评论数据导入成功") + } else { + return + } + } + return +} \ No newline at end of file diff --git a/xf_blog_waline.sql b/xf_blog_waline.sql new file mode 100755 index 0000000..79d339b --- /dev/null +++ b/xf_blog_waline.sql @@ -0,0 +1,148 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- 主机: 172.17.0.3 +-- 生成日期: 2023-12-22 17:37:06 +-- 服务器版本: 8.2.0 +-- PHP 版本: 8.2.13 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- 数据库: `waline` +-- + +-- -------------------------------------------------------- + +-- +-- 表的结构 `wl_comment` +-- + +CREATE TABLE `wl_comment` ( + `id` int UNSIGNED NOT NULL, + `user_id` int DEFAULT NULL, + `comment` text, + `insertedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + `ip` varchar(100) DEFAULT '', + `link` varchar(255) DEFAULT NULL, + `mail` varchar(255) DEFAULT NULL, + `nick` varchar(255) DEFAULT NULL, + `pid` int DEFAULT NULL, + `rid` int DEFAULT NULL, + `sticky` tinyint(1) DEFAULT NULL, + `status` varchar(50) NOT NULL DEFAULT '', + `like` int DEFAULT NULL, + `ua` text, + `url` varchar(255) DEFAULT NULL, + `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + `object_id` varchar(30) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `wl_counter` +-- + +CREATE TABLE `wl_counter` ( + `id` int UNSIGNED NOT NULL, + `time` int DEFAULT NULL, + `reaction0` int DEFAULT NULL, + `reaction1` int DEFAULT NULL, + `reaction2` int DEFAULT NULL, + `reaction3` int DEFAULT NULL, + `reaction4` int DEFAULT NULL, + `reaction5` int DEFAULT NULL, + `reaction6` int DEFAULT NULL, + `reaction7` int DEFAULT NULL, + `reaction8` int DEFAULT NULL, + `url` varchar(255) NOT NULL DEFAULT '', + `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +-- -------------------------------------------------------- + +-- +-- 表的结构 `wl_users` +-- + +CREATE TABLE `wl_users` ( + `id` int UNSIGNED NOT NULL, + `display_name` varchar(255) NOT NULL DEFAULT '', + `email` varchar(255) NOT NULL DEFAULT '', + `password` varchar(255) NOT NULL DEFAULT '', + `type` varchar(50) NOT NULL DEFAULT '', + `label` varchar(255) DEFAULT NULL, + `url` varchar(255) DEFAULT NULL, + `avatar` varchar(255) DEFAULT NULL, + `github` varchar(255) DEFAULT NULL, + `twitter` varchar(255) DEFAULT NULL, + `facebook` varchar(255) DEFAULT NULL, + `google` varchar(255) DEFAULT NULL, + `weibo` varchar(255) DEFAULT NULL, + `qq` varchar(255) DEFAULT NULL, + `2fa` varchar(32) DEFAULT NULL, + `createdAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + `updatedAt` timestamp NULL DEFAULT CURRENT_TIMESTAMP, + `user_id` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + +-- +-- 转储表的索引 +-- + +-- +-- 表的索引 `wl_comment` +-- +ALTER TABLE `wl_comment` + ADD PRIMARY KEY (`id`); + +-- +-- 表的索引 `wl_counter` +-- +ALTER TABLE `wl_counter` + ADD PRIMARY KEY (`id`); + +-- +-- 表的索引 `wl_users` +-- +ALTER TABLE `wl_users` + ADD PRIMARY KEY (`id`); + +-- +-- 在导出的表使用AUTO_INCREMENT +-- + +-- +-- 使用表AUTO_INCREMENT `wl_comment` +-- +ALTER TABLE `wl_comment` + MODIFY `id` int UNSIGNED NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `wl_counter` +-- +ALTER TABLE `wl_counter` + MODIFY `id` int UNSIGNED NOT NULL AUTO_INCREMENT; + +-- +-- 使用表AUTO_INCREMENT `wl_users` +-- +ALTER TABLE `wl_users` + MODIFY `id` int UNSIGNED NOT NULL AUTO_INCREMENT; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;