Browse Source

feat: support version diff (#52)

* feat: implementation diff processor

* fix: checkstyle

* feat: ignore sync if without change

* fix: checkstyle

* feat:add databasir diff api

* feat:update frontend resources
master
vran 3 years ago
committed by GitHub
parent
commit
747ae14da2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      api/src/main/java/com/databasir/api/DocumentController.java
  2. 2
      api/src/main/java/com/databasir/api/Routes.java
  3. 1
      api/src/main/resources/static/css/321.d892cf8e.css
  4. 1
      api/src/main/resources/static/css/907.1437368b.css
  5. 2
      api/src/main/resources/static/index.html
  6. 2
      api/src/main/resources/static/js/117-legacy.f00c6326.js
  7. 2
      api/src/main/resources/static/js/117-legacy.f00c6326.js.map
  8. 2
      api/src/main/resources/static/js/139-legacy.a43600d3.js
  9. 2
      api/src/main/resources/static/js/139-legacy.a43600d3.js.map
  10. 2
      api/src/main/resources/static/js/139.909d89d2.js
  11. 2
      api/src/main/resources/static/js/139.909d89d2.js.map
  12. 33
      api/src/main/resources/static/js/321-legacy.b0227d64.js
  13. 1
      api/src/main/resources/static/js/321-legacy.b0227d64.js.map
  14. 33
      api/src/main/resources/static/js/321.243dc4e3.js
  15. 1
      api/src/main/resources/static/js/321.243dc4e3.js.map
  16. 2
      api/src/main/resources/static/js/355-legacy.023e4ab2.js
  17. 2
      api/src/main/resources/static/js/355-legacy.023e4ab2.js.map
  18. 2
      api/src/main/resources/static/js/355.19f5321e.js
  19. 2
      api/src/main/resources/static/js/355.19f5321e.js.map
  20. 2
      api/src/main/resources/static/js/459-legacy.f2817ef6.js
  21. 2
      api/src/main/resources/static/js/459-legacy.f2817ef6.js.map
  22. 2
      api/src/main/resources/static/js/459.d9a5fc8a.js
  23. 2
      api/src/main/resources/static/js/459.d9a5fc8a.js.map
  24. 2
      api/src/main/resources/static/js/469-legacy.3e02203b.js
  25. 2
      api/src/main/resources/static/js/469-legacy.3e02203b.js.map
  26. 2
      api/src/main/resources/static/js/469.8c3ea567.js
  27. 2
      api/src/main/resources/static/js/469.8c3ea567.js.map
  28. 2
      api/src/main/resources/static/js/564.abfed23d.js
  29. 2
      api/src/main/resources/static/js/564.abfed23d.js.map
  30. 2
      api/src/main/resources/static/js/596-legacy.d1261d0e.js
  31. 2
      api/src/main/resources/static/js/596-legacy.d1261d0e.js.map
  32. 2
      api/src/main/resources/static/js/596.eb4080a7.js
  33. 2
      api/src/main/resources/static/js/596.eb4080a7.js.map
  34. 2
      api/src/main/resources/static/js/719-legacy.85eb5e28.js
  35. 2
      api/src/main/resources/static/js/719-legacy.85eb5e28.js.map
  36. 2
      api/src/main/resources/static/js/719.df03c200.js
  37. 2
      api/src/main/resources/static/js/719.df03c200.js.map
  38. 2
      api/src/main/resources/static/js/754-legacy.2b22ae65.js
  39. 2
      api/src/main/resources/static/js/754-legacy.2b22ae65.js.map
  40. 2
      api/src/main/resources/static/js/754.d037cc5e.js
  41. 2
      api/src/main/resources/static/js/754.d037cc5e.js.map
  42. 2
      api/src/main/resources/static/js/865-legacy.fc2fd7b3.js
  43. 2
      api/src/main/resources/static/js/865-legacy.fc2fd7b3.js.map
  44. 2
      api/src/main/resources/static/js/865.ebbb1893.js
  45. 2
      api/src/main/resources/static/js/865.ebbb1893.js.map
  46. 33
      api/src/main/resources/static/js/907-legacy.cb70ee94.js
  47. 1
      api/src/main/resources/static/js/907-legacy.cb70ee94.js.map
  48. 33
      api/src/main/resources/static/js/907.2782ffff.js
  49. 1
      api/src/main/resources/static/js/907.2782ffff.js.map
  50. 2
      api/src/main/resources/static/js/99-legacy.6cfcb3aa.js
  51. 2
      api/src/main/resources/static/js/99-legacy.6cfcb3aa.js.map
  52. 2
      api/src/main/resources/static/js/99.79a6a4f8.js
  53. 2
      api/src/main/resources/static/js/99.79a6a4f8.js.map
  54. 4
      api/src/main/resources/static/js/app-legacy.3d5e4b5d.js
  55. 2
      api/src/main/resources/static/js/app-legacy.3d5e4b5d.js.map
  56. 4
      api/src/main/resources/static/js/app.08e3c996.js
  57. 2
      api/src/main/resources/static/js/app.08e3c996.js.map
  58. 1
      core/src/main/java/com/databasir/core/domain/DomainErrors.java
  59. 9
      core/src/main/java/com/databasir/core/domain/document/converter/BaseConverter.java
  60. 71
      core/src/main/java/com/databasir/core/domain/document/converter/DatabaseMetaConverter.java
  61. 4
      core/src/main/java/com/databasir/core/domain/document/converter/DocumentPojoConverter.java
  62. 14
      core/src/main/java/com/databasir/core/domain/document/converter/NullToEmpty.java
  63. 54
      core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java
  64. 2
      dao/generated-src/jooq/main/java/com/databasir/dao/tables/TableColumnDocument.java
  65. 4
      dao/generated-src/jooq/main/java/com/databasir/dao/tables/TableDocument.java
  66. 13
      dao/generated-src/jooq/main/java/com/databasir/dao/tables/TableForeignKeyDocument.java
  67. 19
      dao/generated-src/jooq/main/java/com/databasir/dao/tables/pojos/TableForeignKeyDocumentPojo.java
  68. 166
      dao/generated-src/jooq/main/java/com/databasir/dao/tables/records/TableForeignKeyDocumentRecord.java
  69. 0
      dao/src/main/java/com/databasir/dao/converter/.gitkeep
  70. 13
      dao/src/main/resources/db/migration/V1__init.sql
  71. 2
      plugin/build.gradle
  72. 17
      plugin/src/main/java/com/databasir/core/diff/Diffs.java
  73. 11
      plugin/src/main/java/com/databasir/core/diff/data/Diff.java
  74. 9
      plugin/src/main/java/com/databasir/core/diff/data/DiffType.java
  75. 24
      plugin/src/main/java/com/databasir/core/diff/data/FieldDiff.java
  76. 15
      plugin/src/main/java/com/databasir/core/diff/data/RootDiff.java
  77. 14
      plugin/src/main/java/com/databasir/core/diff/processor/ColumnDiffProcessor.java
  78. 81
      plugin/src/main/java/com/databasir/core/diff/processor/DatabaseDiffProcessor.java
  79. 94
      plugin/src/main/java/com/databasir/core/diff/processor/DiffProcessor.java
  80. 24
      plugin/src/main/java/com/databasir/core/diff/processor/ForeignKeyDiffProcessor.java
  81. 14
      plugin/src/main/java/com/databasir/core/diff/processor/IndexDiffProcessor.java
  82. 158
      plugin/src/main/java/com/databasir/core/diff/processor/TableDiffProcessor.java
  83. 14
      plugin/src/main/java/com/databasir/core/diff/processor/TriggerDiffProcessor.java
  84. 6
      plugin/src/main/java/com/databasir/core/meta/data/ColumnMeta.java
  85. 4
      plugin/src/main/java/com/databasir/core/meta/data/DatabaseMeta.java
  86. 8
      plugin/src/main/java/com/databasir/core/meta/data/ForeignKeyMeta.java
  87. 6
      plugin/src/main/java/com/databasir/core/meta/data/IndexMeta.java
  88. 8
      plugin/src/main/java/com/databasir/core/meta/data/TableMeta.java
  89. 6
      plugin/src/main/java/com/databasir/core/meta/data/TriggerMeta.java
  90. 2
      plugin/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcForeignKeyMetaRepository.java
  91. 2
      plugin/src/main/java/com/databasir/core/render/markdown/MarkdownRender.java
  92. 40
      plugin/src/test/java/App.java
  93. 597
      plugin/src/test/java/com/databasir/core/diff/service/DiffsTest.java
  94. 466
      plugin/src/test/resources/ut/diffsTest/diffDatabaseAdded/current.json
  95. 3
      plugin/src/test/resources/ut/diffsTest/diffDatabaseAdded/original.json
  96. 470
      plugin/src/test/resources/ut/diffsTest/diffDatabaseModified/current.json
  97. 470
      plugin/src/test/resources/ut/diffsTest/diffDatabaseModified/original.json
  98. 3
      plugin/src/test/resources/ut/diffsTest/diffDatabaseRemoved/current.json
  99. 466
      plugin/src/test/resources/ut/diffsTest/diffDatabaseRemoved/original.json
  100. 466
      plugin/src/test/resources/ut/diffsTest/diffDatabaseSame/current.json

8
api/src/main/java/com/databasir/api/DocumentController.java

@ -1,6 +1,7 @@
package com.databasir.api;
import com.databasir.common.JsonData;
import com.databasir.core.diff.data.RootDiff;
import com.databasir.core.domain.document.data.DatabaseDocumentResponse;
import com.databasir.core.domain.document.data.DatabaseDocumentSimpleResponse;
import com.databasir.core.domain.document.data.DatabaseDocumentVersionResponse;
@ -39,6 +40,13 @@ public class DocumentController {
return JsonData.ok();
}
@GetMapping(Routes.Document.DIFF)
public JsonData<RootDiff> diff(@PathVariable Integer projectId,
@RequestParam(name = "originalVersion") Long originalVersion,
@RequestParam(required = false) Long currentVersion) {
return JsonData.ok(documentService.diff(projectId, originalVersion, currentVersion));
}
@GetMapping(Routes.Document.GET_ONE)
public JsonData<DatabaseDocumentResponse> getByProjectId(@PathVariable Integer projectId,
@RequestParam(required = false) Long version) {

2
api/src/main/java/com/databasir/api/Routes.java

@ -82,6 +82,8 @@ public interface Routes {
String GET_TABLE_DETAIL = BASE + "/projects/{projectId}/documents/{documentId}/table_documents";
String DIFF = BASE + "/projects/{projectId}/diff_documents";
String EXPORT = BASE + "/projects/{projectId}/document_files";
}

1
api/src/main/resources/static/css/321.d892cf8e.css

@ -0,0 +1 @@
@-webkit-keyframes running-line{to{stroke-dashoffset:-1000}}@keyframes running-line{to{stroke-dashoffset:-1000}}.text{font-size:14px;line-height:1.3rem}.item{margin-top:10px;margin-right:40px}.remark-card{margin-bottom:30px}.remark-header{display:flex;justify-content:space-between;align-items:center}.remark-header .remark-user{color:#6d6d6d}.remark-header .remark-time{color:#6d6d6d;font-size:.8rem;margin-left:10px}.remark-content{white-space:pre-wrap;text-align:left}.badge-item{margin-top:18px;margin-bottom:6px}.h2{font-size:24px;color:#606266;margin-top:13px;margin-bottom:13px}.h2,.h3{font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,,Arial,sans-serif}.h3{font-size:20px;color:#909399;margin-top:18px;margin-bottom:18px}.removed-item{background-color:#fef0f0!important;color:#f56c6c}.added-item{background-color:#f0f9eb!important;color:#67c23a}.modified-item{background-color:#fdf6ec!important;color:#e6a23c}.modified-original-item{background-color:#fdf6ec!important;color:#a8abb2}.span-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;flex:1;display:flex;align-items:left;justify-content:space-between;font-size:14px}.doc-toc-aside{overflow-wrap:break-word;text-overflow:ellipsis;bottom:0;top:100px;position:fixed;overflow-y:hidden;overflow-x:hidden;max-width:var(--el-aside-width);width:var(--el-aside-width);border-width:0 1px 0 0;border-color:#ddd;border-style:solid}.doc-toc-aside:hover{overflow-y:auto;scrollbar-width:thin}

1
api/src/main/resources/static/css/907.1437368b.css

@ -1 +0,0 @@
@-webkit-keyframes running-line{to{stroke-dashoffset:-1000}}@keyframes running-line{to{stroke-dashoffset:-1000}}.text{font-size:14px;line-height:1.3rem}.item{margin-top:10px;margin-right:40px}.remark-card{margin-bottom:30px}.remark-header{display:flex;justify-content:space-between;align-items:center}.remark-header .remark-user{color:#6d6d6d}.remark-header .remark-time{color:#6d6d6d;font-size:.8rem;margin-left:10px}.remark-content{white-space:pre-wrap;text-align:left}.span-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;flex:1;display:flex;align-items:left;justify-content:space-between;font-size:14px}.doc-toc-aside{overflow-wrap:break-word;text-overflow:ellipsis;bottom:0;top:100px;position:fixed;overflow-y:hidden;overflow-x:hidden;max-width:var(--el-aside-width);width:var(--el-aside-width);border-width:0 1px 0 0;border-color:#ddd;border-style:solid}.doc-toc-aside:hover{overflow-y:auto;scrollbar-width:thin}

2
api/src/main/resources/static/index.html

@ -1 +1 @@
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>databasir-frontend</title><script defer="defer" type="module" src="/js/chunk-vendors.45746587.js"></script><script defer="defer" type="module" src="/js/app.e0747db1.js"></script><link href="/css/chunk-vendors.8e1003a6.css" rel="stylesheet"><link href="/css/app.757c1ef3.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors-legacy.54c3660b.js" nomodule></script><script defer="defer" src="/js/app-legacy.e6a59dc2.js" nomodule></script></head><body><noscript><strong>We're sorry but databasir-frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>databasir-frontend</title><script defer="defer" type="module" src="/js/chunk-vendors.45746587.js"></script><script defer="defer" type="module" src="/js/app.08e3c996.js"></script><link href="/css/chunk-vendors.8e1003a6.css" rel="stylesheet"><link href="/css/app.757c1ef3.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors-legacy.54c3660b.js" nomodule></script><script defer="defer" src="/js/app-legacy.3d5e4b5d.js" nomodule></script></head><body><noscript><strong>We're sorry but databasir-frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

2
api/src/main/resources/static/js/117-legacy.72d604e3.js → api/src/main/resources/static/js/117-legacy.f00c6326.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/117-legacy.72d604e3.js.map → api/src/main/resources/static/js/117-legacy.f00c6326.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/139-legacy.e055efed.js → api/src/main/resources/static/js/139-legacy.a43600d3.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/139-legacy.e055efed.js.map → api/src/main/resources/static/js/139-legacy.a43600d3.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/139.299d5af2.js → api/src/main/resources/static/js/139.909d89d2.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/139.299d5af2.js.map → api/src/main/resources/static/js/139.909d89d2.js.map

File diff suppressed because one or more lines are too long

33
api/src/main/resources/static/js/321-legacy.b0227d64.js

File diff suppressed because one or more lines are too long

1
api/src/main/resources/static/js/321-legacy.b0227d64.js.map

File diff suppressed because one or more lines are too long

33
api/src/main/resources/static/js/321.243dc4e3.js

File diff suppressed because one or more lines are too long

1
api/src/main/resources/static/js/321.243dc4e3.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/355-legacy.6051dcfc.js → api/src/main/resources/static/js/355-legacy.023e4ab2.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/355-legacy.6051dcfc.js.map → api/src/main/resources/static/js/355-legacy.023e4ab2.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/355.0fcf5559.js → api/src/main/resources/static/js/355.19f5321e.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/355.0fcf5559.js.map → api/src/main/resources/static/js/355.19f5321e.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/459-legacy.5a5a02e8.js → api/src/main/resources/static/js/459-legacy.f2817ef6.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/459-legacy.5a5a02e8.js.map → api/src/main/resources/static/js/459-legacy.f2817ef6.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/459.22e837b8.js → api/src/main/resources/static/js/459.d9a5fc8a.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/459.22e837b8.js.map → api/src/main/resources/static/js/459.d9a5fc8a.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/469-legacy.19860010.js → api/src/main/resources/static/js/469-legacy.3e02203b.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/469-legacy.19860010.js.map → api/src/main/resources/static/js/469-legacy.3e02203b.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/469.bd114b11.js → api/src/main/resources/static/js/469.8c3ea567.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/469.bd114b11.js.map → api/src/main/resources/static/js/469.8c3ea567.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/564.07fcac27.js → api/src/main/resources/static/js/564.abfed23d.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/564.07fcac27.js.map → api/src/main/resources/static/js/564.abfed23d.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/596-legacy.d38041af.js → api/src/main/resources/static/js/596-legacy.d1261d0e.js

@ -1,2 +1,2 @@
"use strict";(self["webpackChunkdatabasir_frontend"]=self["webpackChunkdatabasir_frontend"]||[]).push([[596],{2631:function(e,t,n){n.r(t),n.d(t,{default:function(){return _}});var r=n(6252),u=(0,r.Uk)(" 系统邮箱设置 "),o=(0,r.Uk)(" : "),l=(0,r.Uk)("保存"),a=(0,r.Uk)("重置");function s(e,t,n,s,i,m){var f=(0,r.up)("box"),d=(0,r.up)("el-icon"),c=(0,r.up)("el-divider"),p=(0,r.up)("el-input"),w=(0,r.up)("el-form-item"),h=(0,r.up)("el-col"),g=(0,r.up)("el-button"),_=(0,r.up)("el-form"),W=(0,r.up)("el-card"),V=(0,r.up)("el-main"),b=(0,r.up)("el-container");return(0,r.wg)(),(0,r.j4)(b,null,{default:(0,r.w5)((function(){return[(0,r.Wm)(V,null,{default:(0,r.w5)((function(){return[(0,r.Wm)(W,{shadow:"hover",style:{"max-width":"600px"}},{default:(0,r.w5)((function(){return[(0,r.Wm)(c,null,{default:(0,r.w5)((function(){return[(0,r.Wm)(d,null,{default:(0,r.w5)((function(){return[(0,r.Wm)(f)]})),_:1}),u]})),_:1}),(0,r.Wm)(_,{model:i.form,"label-position":"top",rules:i.formRule,ref:"formRef",style:{"max-width":"900px"}},{default:(0,r.w5)((function(){return[(0,r.Wm)(w,{label:"邮箱账号",prop:"username"},{default:(0,r.w5)((function(){return[(0,r.Wm)(p,{modelValue:i.form.username,"onUpdate:modelValue":t[0]||(t[0]=function(e){return i.form.username=e}),placeholder:"请输入邮箱账号"},null,8,["modelValue"])]})),_:1}),(0,r.Wm)(w,{label:"邮箱密码",prop:"password"},{default:(0,r.w5)((function(){return[(0,r.Wm)(p,{modelValue:i.form.password,"onUpdate:modelValue":t[1]||(t[1]=function(e){return i.form.password=e}),type:"password",placeholder:"请输入密码","show-password":""},null,8,["modelValue"])]})),_:1}),(0,r.Wm)(w,{label:"SMTP",prop:"smtpHost"},{default:(0,r.w5)((function(){return[(0,r.Wm)(h,{span:12},{default:(0,r.w5)((function(){return[(0,r.Wm)(p,{modelValue:i.form.smtpHost,"onUpdate:modelValue":t[2]||(t[2]=function(e){return i.form.smtpHost=e}),placeholder:"SMTP Host"},null,8,["modelValue"])]})),_:1}),(0,r.Wm)(h,{span:1,style:{"text-align":"center"}},{default:(0,r.w5)((function(){return[o]})),_:1}),(0,r.Wm)(h,{span:6},{default:(0,r.w5)((function(){return[(0,r.Wm)(p,{modelValue:i.form.smtpPort,"onUpdate:modelValue":t[3]||(t[3]=function(e){return i.form.smtpPort=e}),placeholder:"SMTP Port"},null,8,["modelValue"])]})),_:1})]})),_:1}),(0,r.Wm)(w,{style:{"margin-top":"38px"}},{default:(0,r.w5)((function(){return[(0,r.Wm)(g,{type:"primary",onClick:t[4]||(t[4]=function(e){return m.onSubmit("formRef")})},{default:(0,r.w5)((function(){return[l]})),_:1}),(0,r.Wm)(g,{type:"danger",onClick:t[5]||(t[5]=function(e){return m.onReset()})},{default:(0,r.w5)((function(){return[a]})),_:1})]})),_:1})]})),_:1},8,["model","rules"])]})),_:1})]})),_:1})]})),_:1})}var i=n(8534),m=(n(5666),n(3872)),f="/api/v1.0/settings",d=function(){return m.Z.get(f+"/sys_email")},c=function(e){return m.Z.post(f+"/sys_email",e)},p=function(){return m.Z["delete"](f+"/sys_email")},w={data:function(){return{form:{smtpHost:null,smtpPort:null,username:null,password:null},formRule:{username:[this.requiredInputValidRule("请输入邮箱账号"),{type:"email",message:"邮箱格式不正确",trigger:"blur"}],password:[this.requiredInputValidRule("请输入邮箱密码")],smtpHost:[this.requiredInputValidRule("请输入 SMTP 地址")],smtpPort:[this.requiredInputValidRule("请输入 SMTP 端口"),{min:1,max:65535,message:"端口有效值为 1~65535",trigger:"blur"}]}}},mounted:function(){this.fetchSysMail()},methods:{requiredInputValidRule:function(e){return{required:!0,message:e,trigger:"blur"}},fetchSysMail:function(){var e=this;return(0,i.Z)(regeneratorRuntime.mark((function t(){var n;return regeneratorRuntime.wrap((function(t){while(1)switch(t.prev=t.next){case 0:return t.next=2,d().then((function(e){return e.data}));case 2:n=t.sent,n&&(e.form=n);case 4:case"end":return t.stop()}}),t)})))()},onSubmit:function(){var e=this;this.$refs.formRef.validate((function(t){return t?(c(e.form).then((function(t){t.errCode||e.$message.success("更新成功")})),!0):(e.$message.error("请完善表单相关信息!"),!1)}))},onReset:function(){var e=this;this.$confirm("确认重置系统邮件吗?删除后数据将无法恢复","警告",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then((function(){p().then((function(t){t.errCode||(e.form={},e.$message.success("重置成功"))}))}))}}},h=n(3744);const g=(0,h.Z)(w,[["render",s]]);var _=g}}]);
//# sourceMappingURL=596-legacy.d38041af.js.map
//# sourceMappingURL=596-legacy.d1261d0e.js.map

2
api/src/main/resources/static/js/596-legacy.d38041af.js.map → api/src/main/resources/static/js/596-legacy.d1261d0e.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/596.e58d33aa.js → api/src/main/resources/static/js/596.eb4080a7.js

@ -1,2 +1,2 @@
"use strict";(self["webpackChunkdatabasir_frontend"]=self["webpackChunkdatabasir_frontend"]||[]).push([[596],{2631:function(e,l,t){t.r(l),t.d(l,{default:function(){return _}});var r=t(6252);const a=(0,r.Uk)(" 系统邮箱设置 "),s=(0,r.Uk)(" : "),o=(0,r.Uk)("保存"),u=(0,r.Uk)("重置");function m(e,l,t,m,n,d){const p=(0,r.up)("box"),i=(0,r.up)("el-icon"),f=(0,r.up)("el-divider"),c=(0,r.up)("el-input"),h=(0,r.up)("el-form-item"),w=(0,r.up)("el-col"),_=(0,r.up)("el-button"),g=(0,r.up)("el-form"),W=(0,r.up)("el-card"),V=(0,r.up)("el-main"),y=(0,r.up)("el-container");return(0,r.wg)(),(0,r.j4)(y,null,{default:(0,r.w5)((()=>[(0,r.Wm)(V,null,{default:(0,r.w5)((()=>[(0,r.Wm)(W,{shadow:"hover",style:{"max-width":"600px"}},{default:(0,r.w5)((()=>[(0,r.Wm)(f,null,{default:(0,r.w5)((()=>[(0,r.Wm)(i,null,{default:(0,r.w5)((()=>[(0,r.Wm)(p)])),_:1}),a])),_:1}),(0,r.Wm)(g,{model:n.form,"label-position":"top",rules:n.formRule,ref:"formRef",style:{"max-width":"900px"}},{default:(0,r.w5)((()=>[(0,r.Wm)(h,{label:"邮箱账号",prop:"username"},{default:(0,r.w5)((()=>[(0,r.Wm)(c,{modelValue:n.form.username,"onUpdate:modelValue":l[0]||(l[0]=e=>n.form.username=e),placeholder:"请输入邮箱账号"},null,8,["modelValue"])])),_:1}),(0,r.Wm)(h,{label:"邮箱密码",prop:"password"},{default:(0,r.w5)((()=>[(0,r.Wm)(c,{modelValue:n.form.password,"onUpdate:modelValue":l[1]||(l[1]=e=>n.form.password=e),type:"password",placeholder:"请输入密码","show-password":""},null,8,["modelValue"])])),_:1}),(0,r.Wm)(h,{label:"SMTP",prop:"smtpHost"},{default:(0,r.w5)((()=>[(0,r.Wm)(w,{span:12},{default:(0,r.w5)((()=>[(0,r.Wm)(c,{modelValue:n.form.smtpHost,"onUpdate:modelValue":l[2]||(l[2]=e=>n.form.smtpHost=e),placeholder:"SMTP Host"},null,8,["modelValue"])])),_:1}),(0,r.Wm)(w,{span:1,style:{"text-align":"center"}},{default:(0,r.w5)((()=>[s])),_:1}),(0,r.Wm)(w,{span:6},{default:(0,r.w5)((()=>[(0,r.Wm)(c,{modelValue:n.form.smtpPort,"onUpdate:modelValue":l[3]||(l[3]=e=>n.form.smtpPort=e),placeholder:"SMTP Port"},null,8,["modelValue"])])),_:1})])),_:1}),(0,r.Wm)(h,{style:{"margin-top":"38px"}},{default:(0,r.w5)((()=>[(0,r.Wm)(_,{type:"primary",onClick:l[4]||(l[4]=e=>d.onSubmit("formRef"))},{default:(0,r.w5)((()=>[o])),_:1}),(0,r.Wm)(_,{type:"danger",onClick:l[5]||(l[5]=e=>d.onReset())},{default:(0,r.w5)((()=>[u])),_:1})])),_:1})])),_:1},8,["model","rules"])])),_:1})])),_:1})])),_:1})}var n=t(3872);const d="/api/v1.0/settings",p=()=>n.Z.get(d+"/sys_email"),i=e=>n.Z.post(d+"/sys_email",e),f=()=>n.Z["delete"](d+"/sys_email");var c={data(){return{form:{smtpHost:null,smtpPort:null,username:null,password:null},formRule:{username:[this.requiredInputValidRule("请输入邮箱账号"),{type:"email",message:"邮箱格式不正确",trigger:"blur"}],password:[this.requiredInputValidRule("请输入邮箱密码")],smtpHost:[this.requiredInputValidRule("请输入 SMTP 地址")],smtpPort:[this.requiredInputValidRule("请输入 SMTP 端口"),{min:1,max:65535,message:"端口有效值为 1~65535",trigger:"blur"}]}}},mounted(){this.fetchSysMail()},methods:{requiredInputValidRule(e){return{required:!0,message:e,trigger:"blur"}},async fetchSysMail(){const e=await p().then((e=>e.data));e&&(this.form=e)},onSubmit(){this.$refs.formRef.validate((e=>e?(i(this.form).then((e=>{e.errCode||this.$message.success("更新成功")})),!0):(this.$message.error("请完善表单相关信息!"),!1)))},onReset(){this.$confirm("确认重置系统邮件吗?删除后数据将无法恢复","警告",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then((()=>{f().then((e=>{e.errCode||(this.form={},this.$message.success("重置成功"))}))}))}}},h=t(3744);const w=(0,h.Z)(c,[["render",m]]);var _=w}}]);
//# sourceMappingURL=596.e58d33aa.js.map
//# sourceMappingURL=596.eb4080a7.js.map

2
api/src/main/resources/static/js/596.e58d33aa.js.map → api/src/main/resources/static/js/596.eb4080a7.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/719-legacy.94f86cce.js → api/src/main/resources/static/js/719-legacy.85eb5e28.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/719-legacy.94f86cce.js.map → api/src/main/resources/static/js/719-legacy.85eb5e28.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/719.ab8ac0bb.js → api/src/main/resources/static/js/719.df03c200.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/719.ab8ac0bb.js.map → api/src/main/resources/static/js/719.df03c200.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/754-legacy.56f0845e.js → api/src/main/resources/static/js/754-legacy.2b22ae65.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/754-legacy.56f0845e.js.map → api/src/main/resources/static/js/754-legacy.2b22ae65.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/754.3b3a23fa.js → api/src/main/resources/static/js/754.d037cc5e.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/754.3b3a23fa.js.map → api/src/main/resources/static/js/754.d037cc5e.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/865-legacy.3c829294.js → api/src/main/resources/static/js/865-legacy.fc2fd7b3.js

@ -1,2 +1,2 @@
"use strict";(self["webpackChunkdatabasir_frontend"]=self["webpackChunkdatabasir_frontend"]||[]).push([[865],{8865:function(t,n,e){e.r(n),e.d(n,{default:function(){return f}});var i=e(6252),r=e(9963),a=(0,i.Uk)("立即跳转");function o(t,n,e,o,u,l){var s=(0,i.up)("el-button"),c=(0,i.up)("el-result"),d=(0,i.up)("el-main"),f=(0,i.up)("el-container"),g=(0,i.Q2)("loading");return(0,i.wg)(),(0,i.j4)(f,null,{default:(0,i.w5)((function(){return[(0,i.wy)(((0,i.wg)(),(0,i.j4)(d,{class:"login-main"},{default:(0,i.w5)((function(){return[(0,i.wy)((0,i.Wm)(c,{icon:u.icon,title:u.title,"sub-title":u.subTitle},{extra:(0,i.w5)((function(){return[(0,i.Wm)(s,{type:"primary",onClick:n[0]||(n[0]=function(t){return l.toIndexPage()})},{default:(0,i.w5)((function(){return[a]})),_:1})]})),_:1},8,["icon","title","sub-title"]),[[r.F8,!u.loading]])]})),_:1})),[[g,u.loading]])]})),_:1})}var u=e(152),l=e(1836),s={data:function(){return{registrationId:null,icon:"",title:"",subTitle:"",loading:!0}},created:function(){this.registrationId=this.$route.params.id,this.login()},methods:{login:function(){var t=this,n=window.location.href,e=this.$route.query;e.redirect_uri=n,(0,u.rd)(this.registrationId,e).then((function(n){n.errCode?(t.title=n.errMessage,t.icon="error"):(l.E.saveUserLoginData(n.data),t.$store.commit("userUpdate",{nickname:n.data.nickname,username:n.data.username,email:n.data.email,avatar:n.data.avatar}),t.icon="success",t.$router.push({path:"/groups"})),t.loading=!1})).catch((function(n){console.log("login failed: "+n),t.icon="error",t.title="登陆失败,请重试",t.loading=!1}))},toIndexPage:function(){this.$router.push({path:"/"})}}},c=e(3744);const d=(0,c.Z)(s,[["render",o]]);var f=d}}]);
//# sourceMappingURL=865-legacy.3c829294.js.map
//# sourceMappingURL=865-legacy.fc2fd7b3.js.map

2
api/src/main/resources/static/js/865-legacy.3c829294.js.map → api/src/main/resources/static/js/865-legacy.fc2fd7b3.js.map

@ -1 +1 @@
{"version":3,"file":"js/865-legacy.3c829294.js","mappings":"mNAUiE,Q,qKAT7DA,EAAAA,EAAAA,IAaeC,EAAA,M,kBAZX,iBAWU,uBAXVD,EAAAA,EAAAA,IAWUE,EAAA,CAXmBC,MAAM,cAAY,C,kBAC3C,iBASY,WATZC,EAAAA,EAAAA,IASYC,EAAA,CARPC,KAAMC,EAAAA,KACNC,MAAOD,EAAAA,MACP,YAAWA,EAAAA,UAHhB,CAMeE,OAAK,SAChB,iBAAiE,EAAjEL,EAAAA,EAAAA,IAAiEM,EAAA,CAAtDC,KAAK,UAAWC,QAAK,+BAAEC,EAAAA,iBAAlC,C,kBAAiD,iBAAI,O,eAPzD,wCAIaN,EAAAA,e,OALjB,IAAoBA,EAAAA,e,6BA2B5B,GACIO,KADW,WAEP,MAAO,CACHC,eAAgB,KAChBT,KAAM,GACNE,MAAO,GACPQ,SAAU,GACVC,SAAS,IAIjBC,QAXW,WAYPC,KAAKJ,eAAiBI,KAAKC,OAAOC,OAAOC,GACzCH,KAAKI,SAGTC,QAAS,CACJD,MADI,WACI,WACCE,EAAcC,OAAOC,SAASC,KAC9BP,EAASF,KAAKC,OAAOS,MAC3BR,EAAOS,aAAeL,GACtBM,EAAAA,EAAAA,IAAYZ,KAAKJ,eAAgBM,GAAQW,MAAK,SAAAC,GACrCA,EAAKC,SAWN,EAAK1B,MAAQyB,EAAKE,WAClB,EAAK7B,KAAO,UAXZ8B,EAAAA,EAAAA,kBAAuBH,EAAKnB,MAC5B,EAAKuB,OAAOC,OAAO,aAAc,CAC7BC,SAAUN,EAAKnB,KAAKyB,SACpBC,SAAUP,EAAKnB,KAAK0B,SACpBC,MAAOR,EAAKnB,KAAK2B,MACjBC,OAAQT,EAAKnB,KAAK4B,SAEtB,EAAKpC,KAAK,UACV,EAAKqC,QAAQC,KAAK,CAACC,KAAM,aAK7B,EAAK5B,SAAU,KAChB6B,OAAM,SAAAC,GACLC,QAAQC,IAAI,iBAAiBF,GAC7B,EAAKzC,KAAO,QACZ,EAAKE,MAAQ,WACb,EAAKS,SAAU,MAIvBiC,YA7BK,WA8BD/B,KAAKwB,QAAQC,KAAK,CAACC,KAAM,S,UCpErC,MAAMM,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,KAEpE","sources":["webpack://databasir-frontend/./src/views/OAuth2Login.vue","webpack://databasir-frontend/./src/views/OAuth2Login.vue?b6ea"],"sourcesContent":["<template>\r\n <el-container>\r\n <el-main v-loading=\"loading\" class=\"login-main\">\r\n <el-result\r\n :icon=\"icon\"\r\n :title=\"title\"\r\n :sub-title=\"subTitle\"\r\n v-show=\"!loading\"\r\n >\r\n <template #extra>\r\n <el-button type=\"primary\" @click=\"toIndexPage()\">立即跳转</el-button>\r\n </template>\r\n </el-result>\r\n </el-main>\r\n </el-container>\r\n</template>\r\n\r\n<style>\r\n.login-main {\r\n margin: 0 auto;\r\n margin-top: 200px;\r\n}\r\n\r\n</style>\r\n<script>\r\nimport { oauth2Login } from \"../api/Login\"\r\nimport { user } from \"../utils/auth\"\r\n\r\n\r\nexport default {\r\n data() {\r\n return {\r\n registrationId: null,\r\n icon: '',\r\n title: '',\r\n subTitle: '',\r\n loading: true,\r\n }\r\n },\r\n\r\n created() {\r\n this.registrationId = this.$route.params.id\r\n this.login()\r\n },\r\n\r\n methods: {\r\n login() {\r\n const redirectUri = window.location.href\r\n const params = this.$route.query\r\n params.redirect_uri = redirectUri\r\n oauth2Login(this.registrationId, params).then(resp => {\r\n if (!resp.errCode) {\r\n user.saveUserLoginData(resp.data)\r\n this.$store.commit('userUpdate', {\r\n nickname: resp.data.nickname,\r\n username: resp.data.username,\r\n email: resp.data.email,\r\n avatar: resp.data.avatar\r\n })\r\n this.icon='success'\r\n this.$router.push({path: '/groups'})\r\n } else {\r\n this.title = resp.errMessage\r\n this.icon = 'error'\r\n }\r\n this.loading = false\r\n }).catch(err => {\r\n console.log('login failed: '+err)\r\n this.icon = 'error'\r\n this.title = '登陆失败,请重试'\r\n this.loading = false\r\n })\r\n },\r\n\r\n toIndexPage() {\r\n this.$router.push({path: '/'})\r\n }\r\n }\r\n}\r\n</script>","import { render } from \"./OAuth2Login.vue?vue&type=template&id=65bc9922\"\nimport script from \"./OAuth2Login.vue?vue&type=script&lang=js\"\nexport * from \"./OAuth2Login.vue?vue&type=script&lang=js\"\n\nimport \"./OAuth2Login.vue?vue&type=style&index=0&id=65bc9922&lang=css\"\n\nimport exportComponent from \"E:\\\\git_workspace\\\\databasir-frontend\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__"],"names":["_createBlock","_component_el_container","_component_el_main","class","_createVNode","_component_el_result","icon","$data","title","extra","_component_el_button","type","onClick","$options","data","registrationId","subTitle","loading","created","this","$route","params","id","login","methods","redirectUri","window","location","href","query","redirect_uri","oauth2Login","then","resp","errCode","errMessage","user","$store","commit","nickname","username","email","avatar","$router","push","path","catch","err","console","log","toIndexPage","__exports__","render"],"sourceRoot":""}
{"version":3,"file":"js/865-legacy.fc2fd7b3.js","mappings":"mNAUiE,Q,qKAT7DA,EAAAA,EAAAA,IAaeC,EAAA,M,kBAZX,iBAWU,uBAXVD,EAAAA,EAAAA,IAWUE,EAAA,CAXmBC,MAAM,cAAY,C,kBAC3C,iBASY,WATZC,EAAAA,EAAAA,IASYC,EAAA,CARPC,KAAMC,EAAAA,KACNC,MAAOD,EAAAA,MACP,YAAWA,EAAAA,UAHhB,CAMeE,OAAK,SAChB,iBAAiE,EAAjEL,EAAAA,EAAAA,IAAiEM,EAAA,CAAtDC,KAAK,UAAWC,QAAK,+BAAEC,EAAAA,iBAAlC,C,kBAAiD,iBAAI,O,eAPzD,wCAIaN,EAAAA,e,OALjB,IAAoBA,EAAAA,e,6BA2B5B,GACIO,KADW,WAEP,MAAO,CACHC,eAAgB,KAChBT,KAAM,GACNE,MAAO,GACPQ,SAAU,GACVC,SAAS,IAIjBC,QAXW,WAYPC,KAAKJ,eAAiBI,KAAKC,OAAOC,OAAOC,GACzCH,KAAKI,SAGTC,QAAS,CACJD,MADI,WACI,WACCE,EAAcC,OAAOC,SAASC,KAC9BP,EAASF,KAAKC,OAAOS,MAC3BR,EAAOS,aAAeL,GACtBM,EAAAA,EAAAA,IAAYZ,KAAKJ,eAAgBM,GAAQW,MAAK,SAAAC,GACrCA,EAAKC,SAWN,EAAK1B,MAAQyB,EAAKE,WAClB,EAAK7B,KAAO,UAXZ8B,EAAAA,EAAAA,kBAAuBH,EAAKnB,MAC5B,EAAKuB,OAAOC,OAAO,aAAc,CAC7BC,SAAUN,EAAKnB,KAAKyB,SACpBC,SAAUP,EAAKnB,KAAK0B,SACpBC,MAAOR,EAAKnB,KAAK2B,MACjBC,OAAQT,EAAKnB,KAAK4B,SAEtB,EAAKpC,KAAK,UACV,EAAKqC,QAAQC,KAAK,CAACC,KAAM,aAK7B,EAAK5B,SAAU,KAChB6B,OAAM,SAAAC,GACLC,QAAQC,IAAI,iBAAiBF,GAC7B,EAAKzC,KAAO,QACZ,EAAKE,MAAQ,WACb,EAAKS,SAAU,MAIvBiC,YA7BK,WA8BD/B,KAAKwB,QAAQC,KAAK,CAACC,KAAM,S,UCpErC,MAAMM,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,KAEpE","sources":["webpack://databasir-frontend/./src/views/OAuth2Login.vue","webpack://databasir-frontend/./src/views/OAuth2Login.vue?b6ea"],"sourcesContent":["<template>\r\n <el-container>\r\n <el-main v-loading=\"loading\" class=\"login-main\">\r\n <el-result\r\n :icon=\"icon\"\r\n :title=\"title\"\r\n :sub-title=\"subTitle\"\r\n v-show=\"!loading\"\r\n >\r\n <template #extra>\r\n <el-button type=\"primary\" @click=\"toIndexPage()\">立即跳转</el-button>\r\n </template>\r\n </el-result>\r\n </el-main>\r\n </el-container>\r\n</template>\r\n\r\n<style>\r\n.login-main {\r\n margin: 0 auto;\r\n margin-top: 200px;\r\n}\r\n\r\n</style>\r\n<script>\r\nimport { oauth2Login } from \"../api/Login\"\r\nimport { user } from \"../utils/auth\"\r\n\r\n\r\nexport default {\r\n data() {\r\n return {\r\n registrationId: null,\r\n icon: '',\r\n title: '',\r\n subTitle: '',\r\n loading: true,\r\n }\r\n },\r\n\r\n created() {\r\n this.registrationId = this.$route.params.id\r\n this.login()\r\n },\r\n\r\n methods: {\r\n login() {\r\n const redirectUri = window.location.href\r\n const params = this.$route.query\r\n params.redirect_uri = redirectUri\r\n oauth2Login(this.registrationId, params).then(resp => {\r\n if (!resp.errCode) {\r\n user.saveUserLoginData(resp.data)\r\n this.$store.commit('userUpdate', {\r\n nickname: resp.data.nickname,\r\n username: resp.data.username,\r\n email: resp.data.email,\r\n avatar: resp.data.avatar\r\n })\r\n this.icon='success'\r\n this.$router.push({path: '/groups'})\r\n } else {\r\n this.title = resp.errMessage\r\n this.icon = 'error'\r\n }\r\n this.loading = false\r\n }).catch(err => {\r\n console.log('login failed: '+err)\r\n this.icon = 'error'\r\n this.title = '登陆失败,请重试'\r\n this.loading = false\r\n })\r\n },\r\n\r\n toIndexPage() {\r\n this.$router.push({path: '/'})\r\n }\r\n }\r\n}\r\n</script>","import { render } from \"./OAuth2Login.vue?vue&type=template&id=65bc9922\"\nimport script from \"./OAuth2Login.vue?vue&type=script&lang=js\"\nexport * from \"./OAuth2Login.vue?vue&type=script&lang=js\"\n\nimport \"./OAuth2Login.vue?vue&type=style&index=0&id=65bc9922&lang=css\"\n\nimport exportComponent from \"E:\\\\git_workspace\\\\databasir-frontend\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__"],"names":["_createBlock","_component_el_container","_component_el_main","class","_createVNode","_component_el_result","icon","$data","title","extra","_component_el_button","type","onClick","$options","data","registrationId","subTitle","loading","created","this","$route","params","id","login","methods","redirectUri","window","location","href","query","redirect_uri","oauth2Login","then","resp","errCode","errMessage","user","$store","commit","nickname","username","email","avatar","$router","push","path","catch","err","console","log","toIndexPage","__exports__","render"],"sourceRoot":""}

2
api/src/main/resources/static/js/865.ef6dc5a3.js → api/src/main/resources/static/js/865.ebbb1893.js

@ -1,2 +1,2 @@
"use strict";(self["webpackChunkdatabasir_frontend"]=self["webpackChunkdatabasir_frontend"]||[]).push([[865],{8865:function(t,e,i){i.r(e),i.d(e,{default:function(){return h}});var a=i(6252),n=i(9963);const r=(0,a.Uk)("立即跳转");function s(t,e,i,s,o,l){const u=(0,a.up)("el-button"),d=(0,a.up)("el-result"),c=(0,a.up)("el-main"),h=(0,a.up)("el-container"),g=(0,a.Q2)("loading");return(0,a.wg)(),(0,a.j4)(h,null,{default:(0,a.w5)((()=>[(0,a.wy)(((0,a.wg)(),(0,a.j4)(c,{class:"login-main"},{default:(0,a.w5)((()=>[(0,a.wy)((0,a.Wm)(d,{icon:o.icon,title:o.title,"sub-title":o.subTitle},{extra:(0,a.w5)((()=>[(0,a.Wm)(u,{type:"primary",onClick:e[0]||(e[0]=t=>l.toIndexPage())},{default:(0,a.w5)((()=>[r])),_:1})])),_:1},8,["icon","title","sub-title"]),[[n.F8,!o.loading]])])),_:1})),[[g,o.loading]])])),_:1})}var o=i(152),l=i(1836),u={data(){return{registrationId:null,icon:"",title:"",subTitle:"",loading:!0}},created(){this.registrationId=this.$route.params.id,this.login()},methods:{login(){const t=window.location.href,e=this.$route.query;e.redirect_uri=t,(0,o.rd)(this.registrationId,e).then((t=>{t.errCode?(this.title=t.errMessage,this.icon="error"):(l.E.saveUserLoginData(t.data),this.$store.commit("userUpdate",{nickname:t.data.nickname,username:t.data.username,email:t.data.email,avatar:t.data.avatar}),this.icon="success",this.$router.push({path:"/groups"})),this.loading=!1})).catch((t=>{console.log("login failed: "+t),this.icon="error",this.title="登陆失败,请重试",this.loading=!1}))},toIndexPage(){this.$router.push({path:"/"})}}},d=i(3744);const c=(0,d.Z)(u,[["render",s]]);var h=c}}]);
//# sourceMappingURL=865.ef6dc5a3.js.map
//# sourceMappingURL=865.ebbb1893.js.map

2
api/src/main/resources/static/js/865.ef6dc5a3.js.map → api/src/main/resources/static/js/865.ebbb1893.js.map

@ -1 +1 @@
{"version":3,"file":"js/865.ef6dc5a3.js","mappings":"yNAUiE,Q,uKAT7DA,EAAAA,EAAAA,IAaeC,EAAA,M,kBAZX,IAWU,uBAXVD,EAAAA,EAAAA,IAWUE,EAAA,CAXmBC,MAAM,cAAY,C,kBAC3C,IASY,WATZC,EAAAA,EAAAA,IASYC,EAAA,CARPC,KAAMC,EAAAA,KACNC,MAAOD,EAAAA,MACP,YAAWA,EAAAA,UAHhB,CAMeE,OAAK,SAChB,IAAiE,EAAjEL,EAAAA,EAAAA,IAAiEM,EAAA,CAAtDC,KAAK,UAAWC,QAAK,eAAEC,EAAAA,gBAAlC,C,kBAAiD,IAAI,M,cAPzD,wCAIaN,EAAAA,c,OALjB,IAAoBA,EAAAA,c,6BA2B5B,GACIO,OACI,MAAO,CACHC,eAAgB,KAChBT,KAAM,GACNE,MAAO,GACPQ,SAAU,GACVC,SAAS,IAIjBC,UACIC,KAAKJ,eAAiBI,KAAKC,OAAOC,OAAOC,GACzCH,KAAKI,SAGTC,QAAS,CACJD,QACG,MAAME,EAAcC,OAAOC,SAASC,KAC9BP,EAASF,KAAKC,OAAOS,MAC3BR,EAAOS,aAAeL,GACtBM,EAAAA,EAAAA,IAAYZ,KAAKJ,eAAgBM,GAAQW,MAAKC,IACrCA,EAAKC,SAWNf,KAAKX,MAAQyB,EAAKE,WAClBhB,KAAKb,KAAO,UAXZ8B,EAAAA,EAAAA,kBAAuBH,EAAKnB,MAC5BK,KAAKkB,OAAOC,OAAO,aAAc,CAC7BC,SAAUN,EAAKnB,KAAKyB,SACpBC,SAAUP,EAAKnB,KAAK0B,SACpBC,MAAOR,EAAKnB,KAAK2B,MACjBC,OAAQT,EAAKnB,KAAK4B,SAEtBvB,KAAKb,KAAK,UACVa,KAAKwB,QAAQC,KAAK,CAACC,KAAM,aAK7B1B,KAAKF,SAAU,KAChB6B,OAAMC,IACLC,QAAQC,IAAI,iBAAiBF,GAC7B5B,KAAKb,KAAO,QACZa,KAAKX,MAAQ,WACbW,KAAKF,SAAU,MAIvBiC,cACI/B,KAAKwB,QAAQC,KAAK,CAACC,KAAM,S,UCpErC,MAAMM,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,KAEpE","sources":["webpack://databasir-frontend/./src/views/OAuth2Login.vue","webpack://databasir-frontend/./src/views/OAuth2Login.vue?b6ea"],"sourcesContent":["<template>\r\n <el-container>\r\n <el-main v-loading=\"loading\" class=\"login-main\">\r\n <el-result\r\n :icon=\"icon\"\r\n :title=\"title\"\r\n :sub-title=\"subTitle\"\r\n v-show=\"!loading\"\r\n >\r\n <template #extra>\r\n <el-button type=\"primary\" @click=\"toIndexPage()\">立即跳转</el-button>\r\n </template>\r\n </el-result>\r\n </el-main>\r\n </el-container>\r\n</template>\r\n\r\n<style>\r\n.login-main {\r\n margin: 0 auto;\r\n margin-top: 200px;\r\n}\r\n\r\n</style>\r\n<script>\r\nimport { oauth2Login } from \"../api/Login\"\r\nimport { user } from \"../utils/auth\"\r\n\r\n\r\nexport default {\r\n data() {\r\n return {\r\n registrationId: null,\r\n icon: '',\r\n title: '',\r\n subTitle: '',\r\n loading: true,\r\n }\r\n },\r\n\r\n created() {\r\n this.registrationId = this.$route.params.id\r\n this.login()\r\n },\r\n\r\n methods: {\r\n login() {\r\n const redirectUri = window.location.href\r\n const params = this.$route.query\r\n params.redirect_uri = redirectUri\r\n oauth2Login(this.registrationId, params).then(resp => {\r\n if (!resp.errCode) {\r\n user.saveUserLoginData(resp.data)\r\n this.$store.commit('userUpdate', {\r\n nickname: resp.data.nickname,\r\n username: resp.data.username,\r\n email: resp.data.email,\r\n avatar: resp.data.avatar\r\n })\r\n this.icon='success'\r\n this.$router.push({path: '/groups'})\r\n } else {\r\n this.title = resp.errMessage\r\n this.icon = 'error'\r\n }\r\n this.loading = false\r\n }).catch(err => {\r\n console.log('login failed: '+err)\r\n this.icon = 'error'\r\n this.title = '登陆失败,请重试'\r\n this.loading = false\r\n })\r\n },\r\n\r\n toIndexPage() {\r\n this.$router.push({path: '/'})\r\n }\r\n }\r\n}\r\n</script>","import { render } from \"./OAuth2Login.vue?vue&type=template&id=65bc9922\"\nimport script from \"./OAuth2Login.vue?vue&type=script&lang=js\"\nexport * from \"./OAuth2Login.vue?vue&type=script&lang=js\"\n\nimport \"./OAuth2Login.vue?vue&type=style&index=0&id=65bc9922&lang=css\"\n\nimport exportComponent from \"E:\\\\git_workspace\\\\databasir-frontend\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__"],"names":["_createBlock","_component_el_container","_component_el_main","class","_createVNode","_component_el_result","icon","$data","title","extra","_component_el_button","type","onClick","$options","data","registrationId","subTitle","loading","created","this","$route","params","id","login","methods","redirectUri","window","location","href","query","redirect_uri","oauth2Login","then","resp","errCode","errMessage","user","$store","commit","nickname","username","email","avatar","$router","push","path","catch","err","console","log","toIndexPage","__exports__","render"],"sourceRoot":""}
{"version":3,"file":"js/865.ebbb1893.js","mappings":"yNAUiE,Q,uKAT7DA,EAAAA,EAAAA,IAaeC,EAAA,M,kBAZX,IAWU,uBAXVD,EAAAA,EAAAA,IAWUE,EAAA,CAXmBC,MAAM,cAAY,C,kBAC3C,IASY,WATZC,EAAAA,EAAAA,IASYC,EAAA,CARPC,KAAMC,EAAAA,KACNC,MAAOD,EAAAA,MACP,YAAWA,EAAAA,UAHhB,CAMeE,OAAK,SAChB,IAAiE,EAAjEL,EAAAA,EAAAA,IAAiEM,EAAA,CAAtDC,KAAK,UAAWC,QAAK,eAAEC,EAAAA,gBAAlC,C,kBAAiD,IAAI,M,cAPzD,wCAIaN,EAAAA,c,OALjB,IAAoBA,EAAAA,c,6BA2B5B,GACIO,OACI,MAAO,CACHC,eAAgB,KAChBT,KAAM,GACNE,MAAO,GACPQ,SAAU,GACVC,SAAS,IAIjBC,UACIC,KAAKJ,eAAiBI,KAAKC,OAAOC,OAAOC,GACzCH,KAAKI,SAGTC,QAAS,CACJD,QACG,MAAME,EAAcC,OAAOC,SAASC,KAC9BP,EAASF,KAAKC,OAAOS,MAC3BR,EAAOS,aAAeL,GACtBM,EAAAA,EAAAA,IAAYZ,KAAKJ,eAAgBM,GAAQW,MAAKC,IACrCA,EAAKC,SAWNf,KAAKX,MAAQyB,EAAKE,WAClBhB,KAAKb,KAAO,UAXZ8B,EAAAA,EAAAA,kBAAuBH,EAAKnB,MAC5BK,KAAKkB,OAAOC,OAAO,aAAc,CAC7BC,SAAUN,EAAKnB,KAAKyB,SACpBC,SAAUP,EAAKnB,KAAK0B,SACpBC,MAAOR,EAAKnB,KAAK2B,MACjBC,OAAQT,EAAKnB,KAAK4B,SAEtBvB,KAAKb,KAAK,UACVa,KAAKwB,QAAQC,KAAK,CAACC,KAAM,aAK7B1B,KAAKF,SAAU,KAChB6B,OAAMC,IACLC,QAAQC,IAAI,iBAAiBF,GAC7B5B,KAAKb,KAAO,QACZa,KAAKX,MAAQ,WACbW,KAAKF,SAAU,MAIvBiC,cACI/B,KAAKwB,QAAQC,KAAK,CAACC,KAAM,S,UCpErC,MAAMM,GAA2B,OAAgB,EAAQ,CAAC,CAAC,SAASC,KAEpE","sources":["webpack://databasir-frontend/./src/views/OAuth2Login.vue","webpack://databasir-frontend/./src/views/OAuth2Login.vue?b6ea"],"sourcesContent":["<template>\r\n <el-container>\r\n <el-main v-loading=\"loading\" class=\"login-main\">\r\n <el-result\r\n :icon=\"icon\"\r\n :title=\"title\"\r\n :sub-title=\"subTitle\"\r\n v-show=\"!loading\"\r\n >\r\n <template #extra>\r\n <el-button type=\"primary\" @click=\"toIndexPage()\">立即跳转</el-button>\r\n </template>\r\n </el-result>\r\n </el-main>\r\n </el-container>\r\n</template>\r\n\r\n<style>\r\n.login-main {\r\n margin: 0 auto;\r\n margin-top: 200px;\r\n}\r\n\r\n</style>\r\n<script>\r\nimport { oauth2Login } from \"../api/Login\"\r\nimport { user } from \"../utils/auth\"\r\n\r\n\r\nexport default {\r\n data() {\r\n return {\r\n registrationId: null,\r\n icon: '',\r\n title: '',\r\n subTitle: '',\r\n loading: true,\r\n }\r\n },\r\n\r\n created() {\r\n this.registrationId = this.$route.params.id\r\n this.login()\r\n },\r\n\r\n methods: {\r\n login() {\r\n const redirectUri = window.location.href\r\n const params = this.$route.query\r\n params.redirect_uri = redirectUri\r\n oauth2Login(this.registrationId, params).then(resp => {\r\n if (!resp.errCode) {\r\n user.saveUserLoginData(resp.data)\r\n this.$store.commit('userUpdate', {\r\n nickname: resp.data.nickname,\r\n username: resp.data.username,\r\n email: resp.data.email,\r\n avatar: resp.data.avatar\r\n })\r\n this.icon='success'\r\n this.$router.push({path: '/groups'})\r\n } else {\r\n this.title = resp.errMessage\r\n this.icon = 'error'\r\n }\r\n this.loading = false\r\n }).catch(err => {\r\n console.log('login failed: '+err)\r\n this.icon = 'error'\r\n this.title = '登陆失败,请重试'\r\n this.loading = false\r\n })\r\n },\r\n\r\n toIndexPage() {\r\n this.$router.push({path: '/'})\r\n }\r\n }\r\n}\r\n</script>","import { render } from \"./OAuth2Login.vue?vue&type=template&id=65bc9922\"\nimport script from \"./OAuth2Login.vue?vue&type=script&lang=js\"\nexport * from \"./OAuth2Login.vue?vue&type=script&lang=js\"\n\nimport \"./OAuth2Login.vue?vue&type=style&index=0&id=65bc9922&lang=css\"\n\nimport exportComponent from \"E:\\\\git_workspace\\\\databasir-frontend\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__"],"names":["_createBlock","_component_el_container","_component_el_main","class","_createVNode","_component_el_result","icon","$data","title","extra","_component_el_button","type","onClick","$options","data","registrationId","subTitle","loading","created","this","$route","params","id","login","methods","redirectUri","window","location","href","query","redirect_uri","oauth2Login","then","resp","errCode","errMessage","user","$store","commit","nickname","username","email","avatar","$router","push","path","catch","err","console","log","toIndexPage","__exports__","render"],"sourceRoot":""}

33
api/src/main/resources/static/js/907-legacy.cb70ee94.js

File diff suppressed because one or more lines are too long

1
api/src/main/resources/static/js/907-legacy.cb70ee94.js.map

File diff suppressed because one or more lines are too long

33
api/src/main/resources/static/js/907.2782ffff.js

File diff suppressed because one or more lines are too long

1
api/src/main/resources/static/js/907.2782ffff.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/99-legacy.618121ce.js → api/src/main/resources/static/js/99-legacy.6cfcb3aa.js

@ -1,2 +1,2 @@
"use strict";(self["webpackChunkdatabasir_frontend"]=self["webpackChunkdatabasir_frontend"]||[]).push([[99],{5430:function(e,t,a){a.d(t,{v:function(){return r}});var n=a(3872),o="/api/v1.0/operation_logs",r=function(e){return n.Z.get(o,{params:e})}},2099:function(e,t,a){a.r(t),a.d(t,{default:function(){return h}});a(8309);var n=a(6252),o=a(3577),r={key:0},u=(0,n.Uk)("成功"),l={key:1},i=(0,n.Uk)("失败"),p={key:0},c={key:1},g={key:1},s={key:1},d={key:1};function f(e,t,a,f,w,m){var P=(0,n.up)("el-table-column"),j=(0,n.up)("el-option"),h=(0,n.up)("el-select"),v=(0,n.up)("el-tag"),y=(0,n.up)("el-link"),b=(0,n.up)("el-table"),k=(0,n.up)("el-main"),L=(0,n.up)("el-pagination"),O=(0,n.up)("el-footer"),D=(0,n.up)("el-container");return(0,n.wg)(),(0,n.j4)(D,null,{default:(0,n.w5)((function(){return[(0,n.Wm)(k,null,{default:(0,n.w5)((function(){return[(0,n.Wm)(b,{data:w.projectOperationLogPageData.data},{default:(0,n.w5)((function(){return[(0,n.Wm)(P,{prop:"id",label:""}),(0,n.Wm)(P,{prop:"operationModule",label:"系统模块"}),(0,n.Wm)(P,{prop:"operatorNickname",label:"操作人"}),(0,n.Wm)(P,{prop:"operationName",label:"操作"}),(0,n.Wm)(P,{label:"状态"},{header:(0,n.w5)((function(){return[(0,n.Wm)(h,{modelValue:w.projectOperationLogPageQuery.isSuccess,"onUpdate:modelValue":t[0]||(t[0]=function(e){return w.projectOperationLogPageQuery.isSuccess=e}),placeholder:"状态",onChange:m.onQuery,clearable:"",size:"small","tag-type":"success"},{default:(0,n.w5)((function(){return[((0,n.wg)(),(0,n.iD)(n.HY,null,(0,n.Ko)([!0,!1],(function(e){return(0,n.Wm)(j,{key:e,label:e?"成功":"失败",value:e},null,8,["label","value"])})),64))]})),_:1},8,["modelValue","onChange"])]})),default:(0,n.w5)((function(e){return[e.row.isSuccess?((0,n.wg)(),(0,n.iD)("span",r,[(0,n.Wm)(v,{type:"success"},{default:(0,n.w5)((function(){return[u]})),_:1})])):((0,n.wg)(),(0,n.iD)("span",l,[(0,n.Wm)(v,{type:"danger"},{default:(0,n.w5)((function(){return[i]})),_:1})]))]})),_:1}),(0,n.Wm)(P,{label:"错误信息"},{default:(0,n.w5)((function(e){return[e.row.isSuccess?((0,n.wg)(),(0,n.iD)("span",p)):((0,n.wg)(),(0,n.iD)("span",c,(0,o.zw)(e.row.operationResponse.errMessage),1))]})),_:1}),(0,n.Wm)(P,{label:"涉及分组"},{default:(0,n.w5)((function(e){return[e.row.involvedGroup?((0,n.wg)(),(0,n.j4)(y,{key:0},{default:(0,n.w5)((function(){return[(0,n.Uk)((0,o.zw)(e.row.involvedGroup.name),1)]})),_:2},1024)):((0,n.wg)(),(0,n.iD)("span",g," - "))]})),_:1}),(0,n.Wm)(P,{label:"涉及项目"},{default:(0,n.w5)((function(e){return[e.row.involvedProject?((0,n.wg)(),(0,n.j4)(y,{key:0},{default:(0,n.w5)((function(){return[(0,n.Uk)((0,o.zw)(e.row.involvedProject.name),1)]})),_:2},1024)):((0,n.wg)(),(0,n.iD)("span",s," - "))]})),_:1}),(0,n.Wm)(P,{label:"涉及用户"},{default:(0,n.w5)((function(e){return[e.row.involvedUser?((0,n.wg)(),(0,n.j4)(y,{key:0},{default:(0,n.w5)((function(){return[(0,n.Uk)((0,o.zw)(e.row.involvedUser.nickname),1)]})),_:2},1024)):((0,n.wg)(),(0,n.iD)("span",d," - "))]})),_:1}),(0,n.Wm)(P,{prop:"createAt",label:"记录时间"})]})),_:1},8,["data"])]})),_:1}),(0,n.Wm)(O,null,{default:(0,n.w5)((function(){return[(0,n.Wm)(L,{layout:"prev, pager, next","hide-on-single-page":!1,currentPage:w.projectOperationLogPageData.number,"page-size":w.projectOperationLogPageData.size,"page-count":w.projectOperationLogPageData.totalPages,onCurrentChange:m.onProjectOperationLogCurrentPageChange},null,8,["currentPage","page-size","page-count","onCurrentChange"])]})),_:1})]})),_:1})}var w=a(5430),m={data:function(){return{projectOperationLogPageData:{data:[],number:1,size:10,totalElements:0,totalPages:1},projectOperationLogPageQuery:{page:0,size:10,isSuccess:null,involveProjectId:null,module:null}}},created:function(){this.fetchProjectOperationLogs()},methods:{fetchProjectOperationLogs:function(e){var t=this;this.projectOperationLogPageQuery.page=e?e-1:null,(0,w.v)(this.projectOperationLogPageQuery).then((function(e){e.errCode||(t.projectOperationLogPageData.data=e.data.content,t.projectOperationLogPageData.number=e.data.number+1,t.projectOperationLogPageData.size=e.data.size,t.projectOperationLogPageData.totalPages=e.data.totalPages,t.projectOperationLogPageData.totalElements=e.data.totalElements)}))},onProjectOperationLogCurrentPageChange:function(e){e&&e-1!=this.projectOperationLogPageQuery.page&&(this.projectOperationLogPageQuery.page=e-1,this.fetchProjectOperationLogs(e))},onQuery:function(){this.fetchProjectOperationLogs()}}},P=a(3744);const j=(0,P.Z)(m,[["render",f]]);var h=j}}]);
//# sourceMappingURL=99-legacy.618121ce.js.map
//# sourceMappingURL=99-legacy.6cfcb3aa.js.map

2
api/src/main/resources/static/js/99-legacy.618121ce.js.map → api/src/main/resources/static/js/99-legacy.6cfcb3aa.js.map

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/99.c134b829.js → api/src/main/resources/static/js/99.79a6a4f8.js

@ -1,2 +1,2 @@
"use strict";(self["webpackChunkdatabasir_frontend"]=self["webpackChunkdatabasir_frontend"]||[]).push([[99],{5430:function(e,a,t){t.d(a,{v:function(){return n}});var o=t(3872);const r="/api/v1.0/operation_logs",n=e=>o.Z.get(r,{params:e})},2099:function(e,a,t){t.r(a),t.d(a,{default:function(){return j}});var o=t(6252),r=t(3577);const n={key:0},l=(0,o.Uk)("成功"),p={key:1},u=(0,o.Uk)("失败"),i={key:0},g={key:1},s={key:1},c={key:1},d={key:1};function w(e,a,t,w,m,P){const f=(0,o.up)("el-table-column"),h=(0,o.up)("el-option"),j=(0,o.up)("el-select"),v=(0,o.up)("el-tag"),y=(0,o.up)("el-link"),b=(0,o.up)("el-table"),k=(0,o.up)("el-main"),L=(0,o.up)("el-pagination"),O=(0,o.up)("el-footer"),D=(0,o.up)("el-container");return(0,o.wg)(),(0,o.j4)(D,null,{default:(0,o.w5)((()=>[(0,o.Wm)(k,null,{default:(0,o.w5)((()=>[(0,o.Wm)(b,{data:m.projectOperationLogPageData.data},{default:(0,o.w5)((()=>[(0,o.Wm)(f,{prop:"id",label:""}),(0,o.Wm)(f,{prop:"operationModule",label:"系统模块"}),(0,o.Wm)(f,{prop:"operatorNickname",label:"操作人"}),(0,o.Wm)(f,{prop:"operationName",label:"操作"}),(0,o.Wm)(f,{label:"状态"},{header:(0,o.w5)((()=>[(0,o.Wm)(j,{modelValue:m.projectOperationLogPageQuery.isSuccess,"onUpdate:modelValue":a[0]||(a[0]=e=>m.projectOperationLogPageQuery.isSuccess=e),placeholder:"状态",onChange:P.onQuery,clearable:"",size:"small","tag-type":"success"},{default:(0,o.w5)((()=>[((0,o.wg)(),(0,o.iD)(o.HY,null,(0,o.Ko)([!0,!1],(e=>(0,o.Wm)(h,{key:e,label:e?"成功":"失败",value:e},null,8,["label","value"]))),64))])),_:1},8,["modelValue","onChange"])])),default:(0,o.w5)((e=>[e.row.isSuccess?((0,o.wg)(),(0,o.iD)("span",n,[(0,o.Wm)(v,{type:"success"},{default:(0,o.w5)((()=>[l])),_:1})])):((0,o.wg)(),(0,o.iD)("span",p,[(0,o.Wm)(v,{type:"danger"},{default:(0,o.w5)((()=>[u])),_:1})]))])),_:1}),(0,o.Wm)(f,{label:"错误信息"},{default:(0,o.w5)((e=>[e.row.isSuccess?((0,o.wg)(),(0,o.iD)("span",i)):((0,o.wg)(),(0,o.iD)("span",g,(0,r.zw)(e.row.operationResponse.errMessage),1))])),_:1}),(0,o.Wm)(f,{label:"涉及分组"},{default:(0,o.w5)((e=>[e.row.involvedGroup?((0,o.wg)(),(0,o.j4)(y,{key:0},{default:(0,o.w5)((()=>[(0,o.Uk)((0,r.zw)(e.row.involvedGroup.name),1)])),_:2},1024)):((0,o.wg)(),(0,o.iD)("span",s," - "))])),_:1}),(0,o.Wm)(f,{label:"涉及项目"},{default:(0,o.w5)((e=>[e.row.involvedProject?((0,o.wg)(),(0,o.j4)(y,{key:0},{default:(0,o.w5)((()=>[(0,o.Uk)((0,r.zw)(e.row.involvedProject.name),1)])),_:2},1024)):((0,o.wg)(),(0,o.iD)("span",c," - "))])),_:1}),(0,o.Wm)(f,{label:"涉及用户"},{default:(0,o.w5)((e=>[e.row.involvedUser?((0,o.wg)(),(0,o.j4)(y,{key:0},{default:(0,o.w5)((()=>[(0,o.Uk)((0,r.zw)(e.row.involvedUser.nickname),1)])),_:2},1024)):((0,o.wg)(),(0,o.iD)("span",d," - "))])),_:1}),(0,o.Wm)(f,{prop:"createAt",label:"记录时间"})])),_:1},8,["data"])])),_:1}),(0,o.Wm)(O,null,{default:(0,o.w5)((()=>[(0,o.Wm)(L,{layout:"prev, pager, next","hide-on-single-page":!1,currentPage:m.projectOperationLogPageData.number,"page-size":m.projectOperationLogPageData.size,"page-count":m.projectOperationLogPageData.totalPages,onCurrentChange:P.onProjectOperationLogCurrentPageChange},null,8,["currentPage","page-size","page-count","onCurrentChange"])])),_:1})])),_:1})}var m=t(5430),P={data(){return{projectOperationLogPageData:{data:[],number:1,size:10,totalElements:0,totalPages:1},projectOperationLogPageQuery:{page:0,size:10,isSuccess:null,involveProjectId:null,module:null}}},created(){this.fetchProjectOperationLogs()},methods:{fetchProjectOperationLogs(e){this.projectOperationLogPageQuery.page=e?e-1:null,(0,m.v)(this.projectOperationLogPageQuery).then((e=>{e.errCode||(this.projectOperationLogPageData.data=e.data.content,this.projectOperationLogPageData.number=e.data.number+1,this.projectOperationLogPageData.size=e.data.size,this.projectOperationLogPageData.totalPages=e.data.totalPages,this.projectOperationLogPageData.totalElements=e.data.totalElements)}))},onProjectOperationLogCurrentPageChange(e){e&&e-1!=this.projectOperationLogPageQuery.page&&(this.projectOperationLogPageQuery.page=e-1,this.fetchProjectOperationLogs(e))},onQuery(){this.fetchProjectOperationLogs()}}},f=t(3744);const h=(0,f.Z)(P,[["render",w]]);var j=h}}]);
//# sourceMappingURL=99.c134b829.js.map
//# sourceMappingURL=99.79a6a4f8.js.map

2
api/src/main/resources/static/js/99.c134b829.js.map → api/src/main/resources/static/js/99.79a6a4f8.js.map

File diff suppressed because one or more lines are too long

4
api/src/main/resources/static/js/app-legacy.e6a59dc2.js → api/src/main/resources/static/js/app-legacy.3d5e4b5d.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/app-legacy.e6a59dc2.js.map → api/src/main/resources/static/js/app-legacy.3d5e4b5d.js.map

File diff suppressed because one or more lines are too long

4
api/src/main/resources/static/js/app.e0747db1.js → api/src/main/resources/static/js/app.08e3c996.js

File diff suppressed because one or more lines are too long

2
api/src/main/resources/static/js/app.e0747db1.js.map → api/src/main/resources/static/js/app.08e3c996.js.map

File diff suppressed because one or more lines are too long

1
core/src/main/java/com/databasir/core/domain/DomainErrors.java

@ -32,6 +32,7 @@ public enum DomainErrors implements DatabasirErrors {
MUST_NOT_MODIFY_SYSTEM_DEFAULT_DATABASE_TYPE("A_10017", "禁止修改系统默认数据库类型"),
DOWNLOAD_DRIVER_ERROR("A_10018", "驱动下载失败"),
INVALID_DATABASE_TYPE_URL_PATTERN("A_10019", "不合法的 url pattern"),
DOCUMENT_VERSION_IS_INVALID("A_10020", "文档版本不合法"),
;
private final String errCode;

9
core/src/main/java/com/databasir/core/domain/document/converter/BaseConverter.java

@ -1,9 +0,0 @@
package com.databasir.core.domain.document.converter;
public interface BaseConverter {
@NullToEmpty
default String nullToEmpty(String s) {
return s == null ? "" : s;
}
}

71
core/src/main/java/com/databasir/core/domain/document/converter/DatabaseMetaConverter.java

@ -0,0 +1,71 @@
package com.databasir.core.domain.document.converter;
import com.databasir.core.infrastructure.converter.JsonConverter;
import com.databasir.core.meta.data.ColumnMeta;
import com.databasir.core.meta.data.DatabaseMeta;
import com.databasir.core.meta.data.IndexMeta;
import com.databasir.core.meta.data.TableMeta;
import com.databasir.dao.tables.pojos.*;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Mapper(componentModel = "spring", uses = JsonConverter.class)
public interface DatabaseMetaConverter {
default DatabaseMeta of(DatabaseDocumentPojo database,
List<TableDocumentPojo> tables,
List<TableColumnDocumentPojo> columns,
List<TableIndexDocumentPojo> indexes,
List<TableTriggerDocumentPojo> triggers,
List<TableForeignKeyDocumentPojo> foreignKeys) {
var columnMap = groupBy(columns, TableColumnDocumentPojo::getTableDocumentId);
var indexMap = groupBy(indexes, TableIndexDocumentPojo::getTableDocumentId);
var triggerMap = groupBy(triggers, TableTriggerDocumentPojo::getTableDocumentId);
var fkMap = groupBy(foreignKeys, TableForeignKeyDocumentPojo::getTableDocumentId);
return of(database, tables, columnMap, indexMap, triggerMap, fkMap);
}
default DatabaseMeta of(DatabaseDocumentPojo database,
List<TableDocumentPojo> tables,
Map<Integer, List<TableColumnDocumentPojo>> columnGroupByTableId,
Map<Integer, List<TableIndexDocumentPojo>> indexGroupByTableId,
Map<Integer, List<TableTriggerDocumentPojo>> triggerGroupByTableId,
Map<Integer, List<TableForeignKeyDocumentPojo>> fkGroupByTableId) {
List<TableMeta> tableMetas = tables.stream()
.map(table -> {
Integer id = table.getId();
var columns = columnGroupByTableId.getOrDefault(id, Collections.emptyList());
var indexes = indexGroupByTableId.getOrDefault(id, Collections.emptyList());
var triggers = triggerGroupByTableId.getOrDefault(id, Collections.emptyList());
var foreignKeys = fkGroupByTableId.getOrDefault(id, Collections.emptyList());
return of(table, columns, indexes, triggers, foreignKeys);
})
.collect(Collectors.toList());
return of(database, tableMetas);
}
DatabaseMeta of(DatabaseDocumentPojo database, List<TableMeta> tables);
TableMeta of(TableDocumentPojo table,
List<TableColumnDocumentPojo> columns,
List<TableIndexDocumentPojo> indexes,
List<TableTriggerDocumentPojo> triggers,
List<TableForeignKeyDocumentPojo> foreignKeys);
ColumnMeta of(TableColumnDocumentPojo pojo);
@Mapping(target = "isUniqueKey", source = "pojo.isUnique")
@Mapping(target = "columnNames", source = "pojo.columnNameArray")
IndexMeta of(TableIndexDocumentPojo pojo);
default <R> Map<Integer, List<R>> groupBy(List<R> content, Function<R, Integer> idMapping) {
return content.stream()
.collect(Collectors.groupingBy(idMapping));
}
}

4
core/src/main/java/com/databasir/core/domain/document/converter/DocumentPojoConverter.java

@ -14,7 +14,7 @@ import java.util.List;
import java.util.stream.Collectors;
@Mapper(componentModel = "spring", uses = JsonConverter.class, unmappedTargetPolicy = ReportingPolicy.WARN)
public interface DocumentPojoConverter extends BaseConverter {
public interface DocumentPojoConverter {
@Mapping(target = "databaseName", source = "meta.databaseName")
@Mapping(target = "schemaName", source = "meta.schemaName")
@ -23,7 +23,6 @@ public interface DocumentPojoConverter extends BaseConverter {
com.databasir.core.meta.data.DatabaseMeta meta,
Long version);
@Mapping(target = "comment", qualifiedBy = NullToEmpty.class)
TableDocumentPojo toTablePojo(Integer databaseDocumentId,
com.databasir.core.meta.data.TableMeta meta);
@ -35,7 +34,6 @@ public interface DocumentPojoConverter extends BaseConverter {
.collect(Collectors.toList());
}
@Mapping(target = "comment", qualifiedBy = NullToEmpty.class)
TableColumnDocumentPojo toColumnPojo(Integer databaseDocumentId,
Integer tableDocumentId,
ColumnMeta meta);

14
core/src/main/java/com/databasir/core/domain/document/converter/NullToEmpty.java

@ -1,14 +0,0 @@
package com.databasir.core.domain.document.converter;
import org.mapstruct.Qualifier;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface NullToEmpty {
}

54
core/src/main/java/com/databasir/core/domain/document/service/DocumentService.java

@ -2,7 +2,11 @@ package com.databasir.core.domain.document.service;
import com.databasir.core.Databasir;
import com.databasir.core.DatabasirConfig;
import com.databasir.core.diff.Diffs;
import com.databasir.core.diff.data.DiffType;
import com.databasir.core.diff.data.RootDiff;
import com.databasir.core.domain.DomainErrors;
import com.databasir.core.domain.document.converter.DatabaseMetaConverter;
import com.databasir.core.domain.document.converter.DocumentPojoConverter;
import com.databasir.core.domain.document.converter.DocumentResponseConverter;
import com.databasir.core.domain.document.converter.DocumentSimpleResponseConverter;
@ -74,6 +78,8 @@ public class DocumentService {
private final DocumentSimpleResponseConverter documentSimpleResponseConverter;
private final DatabaseMetaConverter databaseMetaConverter;
private final JsonConverter jsonConverter;
private final List<DocumentFileGenerator> documentFileGenerators;
@ -82,19 +88,37 @@ public class DocumentService {
public void syncByProjectId(Integer projectId) {
projectDao.selectOptionalById(projectId)
.orElseThrow(DomainErrors.PROJECT_NOT_FOUND::exception);
DatabaseMeta meta = retrieveDatabaseMeta(projectId);
Optional<DatabaseDocumentPojo> latestDocumentOpt = databaseDocumentDao.selectNotArchivedByProjectId(projectId);
if (latestDocumentOpt.isPresent()) {
DatabaseDocumentPojo latestDocument = latestDocumentOpt.get();
Integer previousDocumentId = latestDocument.getId();
DatabaseMeta current = retrieveDatabaseMeta(projectId);
Optional<DatabaseDocumentPojo> originalOption = databaseDocumentDao.selectNotArchivedByProjectId(projectId);
if (originalOption.isPresent()) {
DatabaseDocumentPojo original = originalOption.get();
DatabaseMeta originalMeta = retrieveOriginalDatabaseMeta(original);
RootDiff diff = Diffs.diff(originalMeta, current);
if (diff.getDiffType() == DiffType.NONE) {
log.info("ignore project {} {} sync data, because without change",
projectId,
original.getDatabaseName());
return;
}
Integer previousDocumentId = original.getId();
// archive old version
databaseDocumentDao.updateIsArchiveById(previousDocumentId, true);
saveNewDocument(meta, latestDocument.getVersion() + 1, latestDocument.getProjectId());
saveNewDocument(current, original.getVersion() + 1, original.getProjectId());
} else {
saveNewDocument(meta, 1L, projectId);
saveNewDocument(current, 1L, projectId);
}
}
private DatabaseMeta retrieveOriginalDatabaseMeta(DatabaseDocumentPojo original) {
Integer docId = original.getId();
List<TableDocumentPojo> tables = tableDocumentDao.selectByDatabaseDocumentId(docId);
List<TableColumnDocumentPojo> columns = tableColumnDocumentDao.selectByDatabaseDocumentId(docId);
List<TableIndexDocumentPojo> indexes = tableIndexDocumentDao.selectByDatabaseMetaId(docId);
List<TableTriggerDocumentPojo> triggers = tableTriggerDocumentDao.selectByDatabaseDocumentId(docId);
List<TableForeignKeyDocumentPojo> fks = tableForeignKeyDocumentDao.selectByDatabaseDocumentId(docId);
return databaseMetaConverter.of(original, tables, columns, indexes, triggers, fks);
}
private DatabaseMeta retrieveDatabaseMeta(Integer projectId) {
ProjectSyncRulePojo rule = projectSyncRuleDao.selectByProjectId(projectId);
DataSourcePojo dataSource = dataSourceDao.selectByProjectId(projectId);
@ -325,4 +349,20 @@ public class DocumentService {
.ifPresent(generator -> generator.generate(context, out));
});
}
public RootDiff diff(Integer projectId, Long originalVersion, Long currentVersion) {
var original = databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, originalVersion)
.orElseThrow(DomainErrors.DOCUMENT_VERSION_IS_INVALID::exception);
DatabaseDocumentPojo current;
if (currentVersion == null) {
current = databaseDocumentDao.selectNotArchivedByProjectId(projectId)
.orElseThrow(DomainErrors.DOCUMENT_VERSION_IS_INVALID::exception);
} else {
current = databaseDocumentDao.selectOptionalByProjectIdAndVersion(projectId, currentVersion)
.orElseThrow(DomainErrors.DOCUMENT_VERSION_IS_INVALID::exception);
}
DatabaseMeta currMeta = retrieveOriginalDatabaseMeta(current);
DatabaseMeta originalMeta = retrieveOriginalDatabaseMeta(original);
return Diffs.diff(originalMeta, currMeta);
}
}

2
dao/generated-src/jooq/main/java/com/databasir/dao/tables/TableColumnDocument.java

@ -81,7 +81,7 @@ public class TableColumnDocument extends TableImpl<TableColumnDocumentRecord> {
/**
* The column <code>databasir.table_column_document.comment</code>.
*/
public final TableField<TableColumnDocumentRecord, String> COMMENT = createField(DSL.name("comment"), SQLDataType.VARCHAR(512).nullable(false), this, "");
public final TableField<TableColumnDocumentRecord, String> COMMENT = createField(DSL.name("comment"), SQLDataType.VARCHAR(512), this, "");
/**
* The column <code>databasir.table_column_document.default_value</code>.

4
dao/generated-src/jooq/main/java/com/databasir/dao/tables/TableDocument.java

@ -69,12 +69,12 @@ public class TableDocument extends TableImpl<TableDocumentRecord> {
/**
* The column <code>databasir.table_document.type</code>.
*/
public final TableField<TableDocumentRecord, String> TYPE = createField(DSL.name("type"), SQLDataType.CLOB.nullable(false), this, "");
public final TableField<TableDocumentRecord, String> TYPE = createField(DSL.name("type"), SQLDataType.VARCHAR(255).nullable(false), this, "");
/**
* The column <code>databasir.table_document.comment</code>.
*/
public final TableField<TableDocumentRecord, String> COMMENT = createField(DSL.name("comment"), SQLDataType.CLOB.nullable(false), this, "");
public final TableField<TableDocumentRecord, String> COMMENT = createField(DSL.name("comment"), SQLDataType.VARCHAR(512), this, "");
/**
* The column <code>databasir.table_document.create_at</code>.

13
dao/generated-src/jooq/main/java/com/databasir/dao/tables/TableForeignKeyDocument.java

@ -19,7 +19,7 @@ import org.jooq.Identity;
import org.jooq.Index;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Row12;
import org.jooq.Row13;
import org.jooq.Schema;
import org.jooq.Table;
import org.jooq.TableField;
@ -69,6 +69,11 @@ public class TableForeignKeyDocument extends TableImpl<TableForeignKeyDocumentRe
*/
public final TableField<TableForeignKeyDocumentRecord, Integer> DATABASE_DOCUMENT_ID = createField(DSL.name("database_document_id"), SQLDataType.INTEGER.nullable(false), this, "");
/**
* The column <code>databasir.table_foreign_key_document.key_seq</code>.
*/
public final TableField<TableForeignKeyDocumentRecord, Integer> KEY_SEQ = createField(DSL.name("key_seq"), SQLDataType.INTEGER.nullable(false).defaultValue(DSL.inline("0", SQLDataType.INTEGER)), this, "");
/**
* The column <code>databasir.table_foreign_key_document.fk_name</code>.
*/
@ -203,11 +208,11 @@ public class TableForeignKeyDocument extends TableImpl<TableForeignKeyDocumentRe
}
// -------------------------------------------------------------------------
// Row12 type methods
// Row13 type methods
// -------------------------------------------------------------------------
@Override
public Row12<Integer, Integer, Integer, String, String, String, String, String, String, String, String, LocalDateTime> fieldsRow() {
return (Row12) super.fieldsRow();
public Row13<Integer, Integer, Integer, Integer, String, String, String, String, String, String, String, String, LocalDateTime> fieldsRow() {
return (Row13) super.fieldsRow();
}
}

19
dao/generated-src/jooq/main/java/com/databasir/dao/tables/pojos/TableForeignKeyDocumentPojo.java

@ -19,6 +19,7 @@ public class TableForeignKeyDocumentPojo implements Serializable {
private Integer id;
private Integer tableDocumentId;
private Integer databaseDocumentId;
private Integer keySeq;
private String fkName;
private String fkTableName;
private String fkColumnName;
@ -35,6 +36,7 @@ public class TableForeignKeyDocumentPojo implements Serializable {
this.id = value.id;
this.tableDocumentId = value.tableDocumentId;
this.databaseDocumentId = value.databaseDocumentId;
this.keySeq = value.keySeq;
this.fkName = value.fkName;
this.fkTableName = value.fkTableName;
this.fkColumnName = value.fkColumnName;
@ -50,6 +52,7 @@ public class TableForeignKeyDocumentPojo implements Serializable {
Integer id,
Integer tableDocumentId,
Integer databaseDocumentId,
Integer keySeq,
String fkName,
String fkTableName,
String fkColumnName,
@ -63,6 +66,7 @@ public class TableForeignKeyDocumentPojo implements Serializable {
this.id = id;
this.tableDocumentId = tableDocumentId;
this.databaseDocumentId = databaseDocumentId;
this.keySeq = keySeq;
this.fkName = fkName;
this.fkTableName = fkTableName;
this.fkColumnName = fkColumnName;
@ -120,6 +124,20 @@ public class TableForeignKeyDocumentPojo implements Serializable {
this.databaseDocumentId = databaseDocumentId;
}
/**
* Getter for <code>databasir.table_foreign_key_document.key_seq</code>.
*/
public Integer getKeySeq() {
return this.keySeq;
}
/**
* Setter for <code>databasir.table_foreign_key_document.key_seq</code>.
*/
public void setKeySeq(Integer keySeq) {
this.keySeq = keySeq;
}
/**
* Getter for <code>databasir.table_foreign_key_document.fk_name</code>.
*/
@ -265,6 +283,7 @@ public class TableForeignKeyDocumentPojo implements Serializable {
sb.append(id);
sb.append(", ").append(tableDocumentId);
sb.append(", ").append(databaseDocumentId);
sb.append(", ").append(keySeq);
sb.append(", ").append(fkName);
sb.append(", ").append(fkTableName);
sb.append(", ").append(fkColumnName);

166
dao/generated-src/jooq/main/java/com/databasir/dao/tables/records/TableForeignKeyDocumentRecord.java

@ -11,8 +11,8 @@ import java.time.LocalDateTime;
import org.jooq.Field;
import org.jooq.Record1;
import org.jooq.Record12;
import org.jooq.Row12;
import org.jooq.Record13;
import org.jooq.Row13;
import org.jooq.impl.UpdatableRecordImpl;
@ -20,7 +20,7 @@ import org.jooq.impl.UpdatableRecordImpl;
* This class is generated by jOOQ.
*/
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableForeignKeyDocumentRecord> implements Record12<Integer, Integer, Integer, String, String, String, String, String, String, String, String, LocalDateTime> {
public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableForeignKeyDocumentRecord> implements Record13<Integer, Integer, Integer, Integer, String, String, String, String, String, String, String, String, LocalDateTime> {
private static final long serialVersionUID = 1L;
@ -70,18 +70,32 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
return (Integer) get(2);
}
/**
* Setter for <code>databasir.table_foreign_key_document.key_seq</code>.
*/
public void setKeySeq(Integer value) {
set(3, value);
}
/**
* Getter for <code>databasir.table_foreign_key_document.key_seq</code>.
*/
public Integer getKeySeq() {
return (Integer) get(3);
}
/**
* Setter for <code>databasir.table_foreign_key_document.fk_name</code>.
*/
public void setFkName(String value) {
set(3, value);
set(4, value);
}
/**
* Getter for <code>databasir.table_foreign_key_document.fk_name</code>.
*/
public String getFkName() {
return (String) get(3);
return (String) get(4);
}
/**
@ -89,7 +103,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* <code>databasir.table_foreign_key_document.fk_table_name</code>.
*/
public void setFkTableName(String value) {
set(4, value);
set(5, value);
}
/**
@ -97,7 +111,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* <code>databasir.table_foreign_key_document.fk_table_name</code>.
*/
public String getFkTableName() {
return (String) get(4);
return (String) get(5);
}
/**
@ -105,7 +119,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* <code>databasir.table_foreign_key_document.fk_column_name</code>.
*/
public void setFkColumnName(String value) {
set(5, value);
set(6, value);
}
/**
@ -113,21 +127,21 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* <code>databasir.table_foreign_key_document.fk_column_name</code>.
*/
public String getFkColumnName() {
return (String) get(5);
return (String) get(6);
}
/**
* Setter for <code>databasir.table_foreign_key_document.pk_name</code>.
*/
public void setPkName(String value) {
set(6, value);
set(7, value);
}
/**
* Getter for <code>databasir.table_foreign_key_document.pk_name</code>.
*/
public String getPkName() {
return (String) get(6);
return (String) get(7);
}
/**
@ -135,7 +149,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* <code>databasir.table_foreign_key_document.pk_table_name</code>.
*/
public void setPkTableName(String value) {
set(7, value);
set(8, value);
}
/**
@ -143,7 +157,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* <code>databasir.table_foreign_key_document.pk_table_name</code>.
*/
public String getPkTableName() {
return (String) get(7);
return (String) get(8);
}
/**
@ -151,7 +165,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* <code>databasir.table_foreign_key_document.pk_column_name</code>.
*/
public void setPkColumnName(String value) {
set(8, value);
set(9, value);
}
/**
@ -159,7 +173,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* <code>databasir.table_foreign_key_document.pk_column_name</code>.
*/
public String getPkColumnName() {
return (String) get(8);
return (String) get(9);
}
/**
@ -167,7 +181,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* NO_ACTION, CASCADE, SET_NULL, SET_DEFAULT
*/
public void setUpdateRule(String value) {
set(9, value);
set(10, value);
}
/**
@ -175,7 +189,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* NO_ACTION, CASCADE, SET_NULL, SET_DEFAULT
*/
public String getUpdateRule() {
return (String) get(9);
return (String) get(10);
}
/**
@ -183,7 +197,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* NO_ACTION, CASCADE, SET_NULL, SET_DEFAULT
*/
public void setDeleteRule(String value) {
set(10, value);
set(11, value);
}
/**
@ -191,21 +205,21 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
* NO_ACTION, CASCADE, SET_NULL, SET_DEFAULT
*/
public String getDeleteRule() {
return (String) get(10);
return (String) get(11);
}
/**
* Setter for <code>databasir.table_foreign_key_document.create_at</code>.
*/
public void setCreateAt(LocalDateTime value) {
set(11, value);
set(12, value);
}
/**
* Getter for <code>databasir.table_foreign_key_document.create_at</code>.
*/
public LocalDateTime getCreateAt() {
return (LocalDateTime) get(11);
return (LocalDateTime) get(12);
}
// -------------------------------------------------------------------------
@ -218,17 +232,17 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
}
// -------------------------------------------------------------------------
// Record12 type implementation
// Record13 type implementation
// -------------------------------------------------------------------------
@Override
public Row12<Integer, Integer, Integer, String, String, String, String, String, String, String, String, LocalDateTime> fieldsRow() {
return (Row12) super.fieldsRow();
public Row13<Integer, Integer, Integer, Integer, String, String, String, String, String, String, String, String, LocalDateTime> fieldsRow() {
return (Row13) super.fieldsRow();
}
@Override
public Row12<Integer, Integer, Integer, String, String, String, String, String, String, String, String, LocalDateTime> valuesRow() {
return (Row12) super.valuesRow();
public Row13<Integer, Integer, Integer, Integer, String, String, String, String, String, String, String, String, LocalDateTime> valuesRow() {
return (Row13) super.valuesRow();
}
@Override
@ -247,47 +261,52 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
}
@Override
public Field<String> field4() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.FK_NAME;
public Field<Integer> field4() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.KEY_SEQ;
}
@Override
public Field<String> field5() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.FK_TABLE_NAME;
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.FK_NAME;
}
@Override
public Field<String> field6() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.FK_COLUMN_NAME;
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.FK_TABLE_NAME;
}
@Override
public Field<String> field7() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.PK_NAME;
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.FK_COLUMN_NAME;
}
@Override
public Field<String> field8() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.PK_TABLE_NAME;
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.PK_NAME;
}
@Override
public Field<String> field9() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.PK_COLUMN_NAME;
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.PK_TABLE_NAME;
}
@Override
public Field<String> field10() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.UPDATE_RULE;
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.PK_COLUMN_NAME;
}
@Override
public Field<String> field11() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.UPDATE_RULE;
}
@Override
public Field<String> field12() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.DELETE_RULE;
}
@Override
public Field<LocalDateTime> field12() {
public Field<LocalDateTime> field13() {
return TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT.CREATE_AT;
}
@ -307,47 +326,52 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
}
@Override
public String component4() {
return getFkName();
public Integer component4() {
return getKeySeq();
}
@Override
public String component5() {
return getFkTableName();
return getFkName();
}
@Override
public String component6() {
return getFkColumnName();
return getFkTableName();
}
@Override
public String component7() {
return getPkName();
return getFkColumnName();
}
@Override
public String component8() {
return getPkTableName();
return getPkName();
}
@Override
public String component9() {
return getPkColumnName();
return getPkTableName();
}
@Override
public String component10() {
return getUpdateRule();
return getPkColumnName();
}
@Override
public String component11() {
return getUpdateRule();
}
@Override
public String component12() {
return getDeleteRule();
}
@Override
public LocalDateTime component12() {
public LocalDateTime component13() {
return getCreateAt();
}
@ -367,47 +391,52 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
}
@Override
public String value4() {
return getFkName();
public Integer value4() {
return getKeySeq();
}
@Override
public String value5() {
return getFkTableName();
return getFkName();
}
@Override
public String value6() {
return getFkColumnName();
return getFkTableName();
}
@Override
public String value7() {
return getPkName();
return getFkColumnName();
}
@Override
public String value8() {
return getPkTableName();
return getPkName();
}
@Override
public String value9() {
return getPkColumnName();
return getPkTableName();
}
@Override
public String value10() {
return getUpdateRule();
return getPkColumnName();
}
@Override
public String value11() {
return getUpdateRule();
}
@Override
public String value12() {
return getDeleteRule();
}
@Override
public LocalDateTime value12() {
public LocalDateTime value13() {
return getCreateAt();
}
@ -430,61 +459,67 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
}
@Override
public TableForeignKeyDocumentRecord value4(String value) {
setFkName(value);
public TableForeignKeyDocumentRecord value4(Integer value) {
setKeySeq(value);
return this;
}
@Override
public TableForeignKeyDocumentRecord value5(String value) {
setFkTableName(value);
setFkName(value);
return this;
}
@Override
public TableForeignKeyDocumentRecord value6(String value) {
setFkColumnName(value);
setFkTableName(value);
return this;
}
@Override
public TableForeignKeyDocumentRecord value7(String value) {
setPkName(value);
setFkColumnName(value);
return this;
}
@Override
public TableForeignKeyDocumentRecord value8(String value) {
setPkTableName(value);
setPkName(value);
return this;
}
@Override
public TableForeignKeyDocumentRecord value9(String value) {
setPkColumnName(value);
setPkTableName(value);
return this;
}
@Override
public TableForeignKeyDocumentRecord value10(String value) {
setUpdateRule(value);
setPkColumnName(value);
return this;
}
@Override
public TableForeignKeyDocumentRecord value11(String value) {
setUpdateRule(value);
return this;
}
@Override
public TableForeignKeyDocumentRecord value12(String value) {
setDeleteRule(value);
return this;
}
@Override
public TableForeignKeyDocumentRecord value12(LocalDateTime value) {
public TableForeignKeyDocumentRecord value13(LocalDateTime value) {
setCreateAt(value);
return this;
}
@Override
public TableForeignKeyDocumentRecord values(Integer value1, Integer value2, Integer value3, String value4, String value5, String value6, String value7, String value8, String value9, String value10, String value11, LocalDateTime value12) {
public TableForeignKeyDocumentRecord values(Integer value1, Integer value2, Integer value3, Integer value4, String value5, String value6, String value7, String value8, String value9, String value10, String value11, String value12, LocalDateTime value13) {
value1(value1);
value2(value2);
value3(value3);
@ -497,6 +532,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
value10(value10);
value11(value11);
value12(value12);
value13(value13);
return this;
}
@ -514,12 +550,13 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
/**
* Create a detached, initialised TableForeignKeyDocumentRecord
*/
public TableForeignKeyDocumentRecord(Integer id, Integer tableDocumentId, Integer databaseDocumentId, String fkName, String fkTableName, String fkColumnName, String pkName, String pkTableName, String pkColumnName, String updateRule, String deleteRule, LocalDateTime createAt) {
public TableForeignKeyDocumentRecord(Integer id, Integer tableDocumentId, Integer databaseDocumentId, Integer keySeq, String fkName, String fkTableName, String fkColumnName, String pkName, String pkTableName, String pkColumnName, String updateRule, String deleteRule, LocalDateTime createAt) {
super(TableForeignKeyDocument.TABLE_FOREIGN_KEY_DOCUMENT);
setId(id);
setTableDocumentId(tableDocumentId);
setDatabaseDocumentId(databaseDocumentId);
setKeySeq(keySeq);
setFkName(fkName);
setFkTableName(fkTableName);
setFkColumnName(fkColumnName);
@ -541,6 +578,7 @@ public class TableForeignKeyDocumentRecord extends UpdatableRecordImpl<TableFore
setId(value.getId());
setTableDocumentId(value.getTableDocumentId());
setDatabaseDocumentId(value.getDatabaseDocumentId());
setKeySeq(value.getKeySeq());
setFkName(value.getFkName());
setFkTableName(value.getFkTableName());
setFkColumnName(value.getFkColumnName());

0
dao/src/main/java/com/databasir/dao/converter/.gitkeep

13
dao/src/main/resources/db/migration/V1__init.sql

@ -136,11 +136,11 @@ CREATE TABLE IF NOT EXISTS table_document
(
id INT PRIMARY KEY AUTO_INCREMENT,
database_document_id INT NOT NULL,
name TEXT NOT NULL,
type TEXT NOT NULL,
comment TEXT NOT NULL,
create_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
database_document_id INT NOT NULL,
name TEXT NOT NULL,
type VARCHAR(255) NOT NULL,
comment VARCHAR(512) DEFAULT NULL,
create_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_database_document_id (database_document_id)
) CHARSET utf8mb4
COLLATE utf8mb4_unicode_ci;
@ -153,7 +153,7 @@ CREATE TABLE IF NOT EXISTS table_column_document
database_document_id INT NOT NULL,
name TEXT NOT NULL,
type VARCHAR(255) NOT NULL,
comment VARCHAR(512) NOT NULL,
comment VARCHAR(512) DEFAULT NULL,
default_value VARCHAR(512) DEFAULT NULL,
size INT NOT NULL,
decimal_digits INT DEFAULT NULL,
@ -171,6 +171,7 @@ CREATE TABLE IF NOT EXISTS table_foreign_key_document
id INT PRIMARY KEY AUTO_INCREMENT,
table_document_id INT NOT NULL,
database_document_id INT NOT NULL,
key_seq INT NOT NULL DEFAULT 0,
fk_name VARCHAR(255) DEFAULT NULL,
fk_table_name VARCHAR(512) NOT NULL,
fk_column_name VARCHAR(512) NOT NULL,

2
plugin/build.gradle

@ -2,4 +2,6 @@ dependencies {
testImplementation 'mysql:mysql-connector-java:8.0.27'
implementation 'org.commonmark:commonmark:0.18.1'
implementation 'org.freemarker:freemarker:2.3.31'
testImplementation "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}"
testImplementation "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}"
}

17
plugin/src/main/java/com/databasir/core/diff/Diffs.java

@ -0,0 +1,17 @@
package com.databasir.core.diff;
import com.databasir.core.diff.data.RootDiff;
import com.databasir.core.diff.processor.DatabaseDiffProcessor;
import com.databasir.core.meta.data.DatabaseMeta;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Diffs {
private static final DatabaseDiffProcessor databaseDiffProcessor = new DatabaseDiffProcessor();
public static RootDiff diff(DatabaseMeta original, DatabaseMeta current) {
return databaseDiffProcessor.process(original, current);
}
}

11
plugin/src/main/java/com/databasir/core/diff/data/Diff.java

@ -0,0 +1,11 @@
package com.databasir.core.diff.data;
public interface Diff {
DiffType getDiffType();
Object getOriginal();
Object getCurrent();
}

9
plugin/src/main/java/com/databasir/core/diff/data/DiffType.java

@ -0,0 +1,9 @@
package com.databasir.core.diff.data;
public enum DiffType {
NONE, ADDED, REMOVED, MODIFIED;
public static boolean isModified(DiffType type) {
return type != null && type != NONE;
}
}

24
plugin/src/main/java/com/databasir/core/diff/data/FieldDiff.java

@ -0,0 +1,24 @@
package com.databasir.core.diff.data;
import lombok.Builder;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
@Builder
public class FieldDiff implements Diff {
private String fieldName;
private DiffType diffType;
private Object original;
private Object current;
@Builder.Default
private List<FieldDiff> fields = new ArrayList<>();
}

15
plugin/src/main/java/com/databasir/core/diff/data/RootDiff.java

@ -0,0 +1,15 @@
package com.databasir.core.diff.data;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class RootDiff {
private DiffType diffType;
private List<FieldDiff> fields = new ArrayList<>();
}

14
plugin/src/main/java/com/databasir/core/diff/processor/ColumnDiffProcessor.java

@ -0,0 +1,14 @@
package com.databasir.core.diff.processor;
import com.databasir.core.diff.data.FieldDiff;
import com.databasir.core.meta.data.ColumnMeta;
import java.util.List;
public class ColumnDiffProcessor implements DiffProcessor<ColumnMeta> {
@Override
public FieldDiff process(String fieldName, List<ColumnMeta> original, List<ColumnMeta> current) {
return diffTableField(original, current, fieldName, ColumnMeta::getName);
}
}

81
plugin/src/main/java/com/databasir/core/diff/processor/DatabaseDiffProcessor.java

@ -0,0 +1,81 @@
package com.databasir.core.diff.processor;
import com.databasir.core.diff.data.DiffType;
import com.databasir.core.diff.data.FieldDiff;
import com.databasir.core.diff.data.RootDiff;
import com.databasir.core.meta.data.DatabaseMeta;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@Slf4j
public class DatabaseDiffProcessor {
private final TableDiffProcessor tableDiffProcessor = new TableDiffProcessor();
private static final DatabaseMeta EMPTY = DatabaseMeta.builder().build();
public RootDiff process(DatabaseMeta original, DatabaseMeta current) {
DiffType diffType = null;
if (original == null && current != null) {
diffType = DiffType.ADDED;
}
if (original != null && current == null) {
diffType = DiffType.REMOVED;
}
List<FieldDiff> fields = diffDatabaseFields(
Objects.requireNonNullElse(original, EMPTY),
Objects.requireNonNullElse(current, EMPTY)
);
boolean isModified = fields.stream().anyMatch(f -> DiffType.isModified(f.getDiffType()));
if (diffType == null) {
diffType = isModified ? DiffType.MODIFIED : DiffType.NONE;
}
RootDiff diff = new RootDiff();
diff.setFields(fields);
diff.setDiffType(diffType);
return diff;
}
private List<FieldDiff> diffDatabaseFields(DatabaseMeta original, DatabaseMeta current) {
Class<DatabaseMeta> clazz = DatabaseMeta.class;
Field[] fields = clazz.getDeclaredFields();
List<FieldDiff> diffs = new ArrayList<>(32);
// ignore tables diff
Arrays.stream(fields)
.filter(field -> !Objects.equals(field.getName(), "tables"))
.forEach(field -> {
try {
field.setAccessible(true);
Object originalValue = original == null ? null : field.get(original);
Object currentValue = current == null ? null : field.get(current);
if (!Objects.equals(originalValue, currentValue)) {
DiffType diffType;
if (originalValue == null) {
diffType = DiffType.ADDED;
} else if (currentValue == null) {
diffType = DiffType.REMOVED;
} else {
diffType = DiffType.MODIFIED;
}
diffs.add(FieldDiff.builder()
.diffType(diffType)
.fieldName(field.getName())
.original(originalValue)
.current(currentValue)
.build());
}
} catch (IllegalAccessException e) {
log.error("diff field failed", e);
}
});
FieldDiff tablesField = tableDiffProcessor.process("tables", original.getTables(), current.getTables());
diffs.add(tablesField);
return diffs;
}
}

94
plugin/src/main/java/com/databasir/core/diff/processor/DiffProcessor.java

@ -0,0 +1,94 @@
package com.databasir.core.diff.processor;
import com.databasir.core.diff.data.DiffType;
import com.databasir.core.diff.data.FieldDiff;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
public interface DiffProcessor<T> {
FieldDiff process(String fieldName, List<T> original, List<T> current);
default FieldDiff diffTableField(List<T> original,
List<T> current,
String fieldName,
Function<T, String> identity) {
Map<String, T> originalMap = toMap(original, identity);
Map<String, T> currentMap = toMap(current, identity);
List<FieldDiff> columnFieldDiffs = new ArrayList<>(32);
// removed
List<FieldDiff> removedFields = originalRemovedField(originalMap, currentMap);
columnFieldDiffs.addAll(removedFields);
// added
List<FieldDiff> addedFields = currentAddedField(originalMap, currentMap);
columnFieldDiffs.addAll(addedFields);
// modified
List<FieldDiff> modifiedFields = modifiedField(originalMap, currentMap);
columnFieldDiffs.addAll(modifiedFields);
return FieldDiff.builder()
.fieldName(fieldName)
.diffType(columnFieldDiffs.isEmpty() ? DiffType.NONE : DiffType.MODIFIED)
.fields(columnFieldDiffs)
.build();
}
default Map<String, T> toMap(List<T> content, Function<T, String> idMapping) {
return content
.stream()
.collect(Collectors.toMap(idMapping, Function.identity()));
}
default List<FieldDiff> originalRemovedField(Map<String, T> originalMapById,
Map<String, T> currentMapById) {
return originalMapById.entrySet()
.stream()
.filter(entry -> !currentMapById.containsKey(entry.getKey()))
.map(entry -> FieldDiff.builder()
.fieldName(entry.getKey())
.original(entry.getValue())
.diffType(DiffType.REMOVED)
.build())
.collect(Collectors.toList());
}
default List<FieldDiff> currentAddedField(Map<String, T> originalMapById,
Map<String, T> currentMapById) {
return currentMapById.entrySet()
.stream()
.filter(entry -> !originalMapById.containsKey(entry.getKey()))
.map(entry -> FieldDiff.builder()
.fieldName(entry.getKey())
.current(entry.getValue())
.diffType(DiffType.ADDED)
.build())
.collect(Collectors.toList());
}
default List<FieldDiff> modifiedField(Map<String, T> original,
Map<String, T> current) {
List<FieldDiff> diff = new ArrayList<>();
original.entrySet()
.stream()
.filter(entry -> current.containsKey(entry.getKey()))
.forEach(entry -> {
T originalValue = entry.getValue();
T currentValue = current.get(entry.getKey());
if (!Objects.equals(originalValue, currentValue)) {
FieldDiff fieldDiff = FieldDiff.builder()
.fieldName(entry.getKey())
.original(originalValue)
.current(currentValue)
.diffType(DiffType.MODIFIED)
.build();
diff.add(fieldDiff);
}
});
return diff;
}
}

24
plugin/src/main/java/com/databasir/core/diff/processor/ForeignKeyDiffProcessor.java

@ -0,0 +1,24 @@
package com.databasir.core.diff.processor;
import com.databasir.core.diff.data.FieldDiff;
import com.databasir.core.meta.data.ForeignKeyMeta;
import java.util.List;
public class ForeignKeyDiffProcessor implements DiffProcessor<ForeignKeyMeta> {
@Override
public FieldDiff process(String fieldName, List<ForeignKeyMeta> original, List<ForeignKeyMeta> current) {
return diffTableField(
original,
current,
"foreignKeys",
fk -> {
if (fk.getFkName() == null) {
return fk.getFkTableName() + "." + fk.getFkColumnName() + "." + fk.getKeySeq();
} else {
return fk.getFkName();
}
});
}
}

14
plugin/src/main/java/com/databasir/core/diff/processor/IndexDiffProcessor.java

@ -0,0 +1,14 @@
package com.databasir.core.diff.processor;
import com.databasir.core.diff.data.FieldDiff;
import com.databasir.core.meta.data.IndexMeta;
import java.util.List;
public class IndexDiffProcessor implements DiffProcessor<IndexMeta> {
@Override
public FieldDiff process(String fieldName, List<IndexMeta> original, List<IndexMeta> current) {
return diffTableField(original, current, fieldName, IndexMeta::getName);
}
}

158
plugin/src/main/java/com/databasir/core/diff/processor/TableDiffProcessor.java

@ -0,0 +1,158 @@
package com.databasir.core.diff.processor;
import com.databasir.core.diff.data.DiffType;
import com.databasir.core.diff.data.FieldDiff;
import com.databasir.core.meta.data.TableMeta;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class TableDiffProcessor implements DiffProcessor<TableMeta> {
private final IndexDiffProcessor indexDiffProcessor = new IndexDiffProcessor();
private final ColumnDiffProcessor columnDiffProcessor = new ColumnDiffProcessor();
private final TriggerDiffProcessor triggerDiffProcessor = new TriggerDiffProcessor();
private final ForeignKeyDiffProcessor foreignKeyDiffProcessor = new ForeignKeyDiffProcessor();
private static final TableMeta EMPTY = new TableMeta();
@Override
public FieldDiff process(String fieldName, List<TableMeta> original, List<TableMeta> current) {
// diff tables field
Map<String, TableMeta> originalMap = toMap(original, TableMeta::getName);
Map<String, TableMeta> currentMap = toMap(current, TableMeta::getName);
List<FieldDiff> tables = new ArrayList<>();
List<TableMeta> added = added(originalMap, currentMap);
List<TableMeta> removed = removed(originalMap, currentMap);
// added
List<FieldDiff> addedFields = added.stream()
.map(table -> diffTableField(EMPTY, table))
.collect(Collectors.toList());
tables.addAll(addedFields);
// removed
List<FieldDiff> removedFields = removed.stream()
.map(table -> diffTableField(table, EMPTY))
.collect(Collectors.toList());
tables.addAll(removedFields);
// modified
List<FieldDiff> modified = originalMap.entrySet()
.stream()
.filter(entry -> currentMap.containsKey(entry.getKey()))
.filter(entry -> !Objects.equals(entry.getValue(), currentMap.get(entry.getKey())))
.map(entry -> {
TableMeta originalValue = entry.getValue();
TableMeta currentValue = currentMap.get(entry.getKey());
return diffTableField(originalValue, currentValue);
})
.collect(Collectors.toList());
tables.addAll(modified);
DiffType tablesDiffType;
if (!modified.isEmpty()) {
tablesDiffType = DiffType.MODIFIED;
} else if (!addedFields.isEmpty()) {
tablesDiffType = DiffType.ADDED;
} else if (!removedFields.isEmpty()) {
tablesDiffType = DiffType.REMOVED;
} else {
tablesDiffType = DiffType.NONE;
}
FieldDiff tablesField = FieldDiff.builder()
.diffType(tablesDiffType)
.fieldName(fieldName)
.fields(tables)
.build();
return tablesField;
}
private List<TableMeta> added(Map<String, TableMeta> originalMap,
Map<String, TableMeta> currentMap) {
return currentMap.entrySet()
.stream()
.filter(entry -> !originalMap.containsKey(entry.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
}
private List<TableMeta> removed(Map<String, TableMeta> originalMap,
Map<String, TableMeta> currentMap) {
return originalMap.entrySet()
.stream()
.filter(entry -> !currentMap.containsKey(entry.getKey()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
}
private FieldDiff diffTableField(TableMeta original, TableMeta current) {
FieldDiff columns =
columnDiffProcessor.process("columns", original.getColumns(), current.getColumns());
FieldDiff indexes =
indexDiffProcessor.process("indexes", original.getIndexes(), current.getIndexes());
FieldDiff triggers =
triggerDiffProcessor.process("triggers", original.getTriggers(), current.getTriggers());
FieldDiff foreignKeys =
foreignKeyDiffProcessor.process("foreignKeys", original.getForeignKeys(), current.getForeignKeys());
List<FieldDiff> otherFields = fields(original, current);
List<FieldDiff> fields = new ArrayList<>();
fields.add(columns);
fields.add(indexes);
fields.add(foreignKeys);
fields.add(triggers);
fields.addAll(otherFields);
DiffType diffType;
if (original == EMPTY) {
diffType = DiffType.ADDED;
} else if (current == EMPTY) {
diffType = DiffType.REMOVED;
} else {
diffType = DiffType.MODIFIED;
}
return FieldDiff.builder()
.diffType(diffType)
.fieldName(original == EMPTY ? current.getName() : original.getName())
.original(current == EMPTY ? original : null)
.current(original == EMPTY ? current : null)
.fields(fields)
.build();
}
private List<FieldDiff> fields(TableMeta original, TableMeta current) {
List<FieldDiff> fields = new ArrayList<>();
// ignore tables diff
Class<TableMeta> clazz = TableMeta.class;
List<String> ignoredFields = List.of("columns", "indexes", "triggers", "foreignKeys");
Arrays.stream(clazz.getDeclaredFields())
.filter(field -> !ignoredFields.contains(field.getName()))
.forEach(field -> {
try {
field.setAccessible(true);
Object originalValue = original == null ? null : field.get(original);
Object currentValue = current == null ? null : field.get(current);
if (!Objects.equals(originalValue, currentValue)) {
DiffType diffType;
if (originalValue == null) {
diffType = DiffType.ADDED;
} else if (currentValue == null) {
diffType = DiffType.REMOVED;
} else {
diffType = DiffType.MODIFIED;
}
fields.add(FieldDiff.builder()
.diffType(diffType)
.fieldName(field.getName())
.original(originalValue)
.current(currentValue)
.build());
}
} catch (IllegalAccessException e) {
log.error("diff field failed", e);
}
});
return fields;
}
}

14
plugin/src/main/java/com/databasir/core/diff/processor/TriggerDiffProcessor.java

@ -0,0 +1,14 @@
package com.databasir.core.diff.processor;
import com.databasir.core.diff.data.FieldDiff;
import com.databasir.core.meta.data.TriggerMeta;
import java.util.List;
public class TriggerDiffProcessor implements DiffProcessor<TriggerMeta> {
@Override
public FieldDiff process(String fieldName, List<TriggerMeta> original, List<TriggerMeta> current) {
return diffTableField(original, current, fieldName, TriggerMeta::getName);
}
}

6
plugin/src/main/java/com/databasir/core/meta/data/ColumnMeta.java

@ -1,10 +1,14 @@
package com.databasir.core.meta.data;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ColumnMeta {
private String name;

4
plugin/src/main/java/com/databasir/core/meta/data/DatabaseMeta.java

@ -1,12 +1,16 @@
package com.databasir.core.meta.data;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DatabaseMeta {

8
plugin/src/main/java/com/databasir/core/meta/data/ForeignKeyMeta.java

@ -1,12 +1,18 @@
package com.databasir.core.meta.data;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ForeignKeyMeta {
private Integer keySeq;
/**
* may null
*/

6
plugin/src/main/java/com/databasir/core/meta/data/IndexMeta.java

@ -1,13 +1,17 @@
package com.databasir.core.meta.data;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.List;
@Data
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class IndexMeta {
private String name;

8
plugin/src/main/java/com/databasir/core/meta/data/TableMeta.java

@ -1,13 +1,17 @@
package com.databasir.core.meta.data;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Collections;
import java.util.List;
@Data
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TableMeta {
private String name;
@ -27,6 +31,4 @@ public class TableMeta {
@Builder.Default
private List<ForeignKeyMeta> foreignKeys = Collections.emptyList();
private String remark;
}

6
plugin/src/main/java/com/databasir/core/meta/data/TriggerMeta.java

@ -1,13 +1,17 @@
package com.databasir.core.meta.data;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* now: only support mysql, postgresql.
*/
@Data
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TriggerMeta {
private String name;

2
plugin/src/main/java/com/databasir/core/meta/repository/impl/jdbc/JdbcForeignKeyMetaRepository.java

@ -41,8 +41,10 @@ public class JdbcForeignKeyMetaRepository implements ForeignKeyMetaRepository {
String pkColumnName = keyResult.getString("PKCOLUMN_NAME");
String pkName = keyResult.getString("PK_NAME");
int updateRule = keyResult.getInt("UPDATE_RULE");
int keySeq = keyResult.getInt("KEY_SEQ");
int deleteRule = keyResult.getInt("DELETE_RULE");
ForeignKeyMeta meta = ForeignKeyMeta.builder()
.keySeq(keySeq)
.fkTableName(fkTableName)
.fkColumnName(fkColumnName)
.fkName(fkName)

2
plugin/src/main/java/com/databasir/core/render/markdown/MarkdownRender.java

@ -51,7 +51,7 @@ public class MarkdownRender implements Render {
private void buildTableName(MarkdownBuilder contentBuilder, TableMeta table) {
String tableName;
if (table.getComment() == null || table.getComment().trim().isEmpty()) {
if (table.getComment().isEmpty()) {
tableName = table.getName();
} else {
tableName = table.getName() + "(" + table.getComment() + ")";

40
plugin/src/test/java/App.java

@ -1,40 +0,0 @@
import com.databasir.core.Databasir;
import com.databasir.core.meta.data.DatabaseMeta;
import org.junit.jupiter.api.Test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class App {
@Test
public void testRenderAsMarkdown() throws SQLException, ClassNotFoundException {
try (FileOutputStream out = new FileOutputStream("demo.md")) {
Connection connection = getJdbcConnection();
Databasir databasir = Databasir.of();
DatabaseMeta doc = databasir.get(connection, "demo").orElseThrow();
databasir.renderAsMarkdown(doc, out);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
private static Connection getJdbcConnection() throws SQLException, ClassNotFoundException {
// get database connection
Class.forName("com.mysql.cj.jdbc.Driver");
Properties info = new Properties();
info.put("user", "root");
info.put("password", "123456");
// this config is used by mysql
info.put("useInformationSchema", "true");
String url = "jdbc:mysql://localhost:3306/demo?"
+ "useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true";
return DriverManager.getConnection(url, info);
}
}

597
plugin/src/test/java/com/databasir/core/diff/service/DiffsTest.java

@ -0,0 +1,597 @@
package com.databasir.core.diff.service;
import com.databasir.core.diff.Diffs;
import com.databasir.core.diff.data.DiffType;
import com.databasir.core.diff.data.FieldDiff;
import com.databasir.core.diff.data.RootDiff;
import com.databasir.core.meta.data.*;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TimeZone;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.*;
class DiffsTest {
private static ObjectMapper objectMapper;
@BeforeAll
static void init() {
objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT)
.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.disable(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)
.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS)
.setTimeZone(TimeZone.getDefault());
}
@Test
void diffEmptyDatabaseSame() {
DatabaseMeta original = DatabaseMeta.builder().build();
DatabaseMeta current = DatabaseMeta.builder().build();
RootDiff diff = Diffs.diff(original, current);
assertEquals(DiffType.NONE, diff.getDiffType());
}
@Test
void diffDatabaseSame() {
DatabaseMeta original = load("ut/diffsTest/diffDatabaseSame/original.json");
DatabaseMeta current = load("ut/diffsTest/diffDatabaseSame/current.json");
RootDiff diff = Diffs.diff(original, current);
assertEquals(DiffType.NONE, diff.getDiffType());
assertSame(1, diff.getFields().size());
FieldDiff tableField = diff.getFields().iterator().next();
assertEquals("tables", tableField.getFieldName());
assertEquals(DiffType.NONE, tableField.getDiffType());
assertTrue(tableField.getFields().isEmpty());
}
@Test
void diffDatabaseAdded() {
DatabaseMeta current = load("ut/diffsTest/diffDatabaseAdded/current.json");
RootDiff diff = Diffs.diff(null, current);
assertEquals(DiffType.ADDED, diff.getDiffType());
}
@Test
void diffDatabaseRemoved() {
DatabaseMeta original = load("ut/diffsTest/diffDatabaseRemoved/original.json");
RootDiff diff = Diffs.diff(original, null);
assertEquals(DiffType.REMOVED, diff.getDiffType());
}
@Test
void diffDatabaseModified() {
DatabaseMeta original = load("ut/diffsTest/diffDatabaseModified/original.json");
DatabaseMeta current = load("ut/diffsTest/diffDatabaseModified/current.json");
// database
RootDiff diff = Diffs.diff(original, current);
assertEquals(DiffType.MODIFIED, diff.getDiffType());
assertSame(2, diff.getFields().size());
Map<String, FieldDiff> diffMap = diff.getFields()
.stream()
.collect(Collectors.toMap(d -> d.getFieldName(), Function.identity()));
// productVersion
assertTrue(diffMap.containsKey("productVersion"));
assertIsModified(diffMap.get("productVersion"));
assertEquals(original.getProductVersion(), diffMap.get("productVersion").getOriginal());
assertEquals(current.getProductVersion(), diffMap.get("productVersion").getCurrent());
// tables
assertTrue(diffMap.containsKey("tables"));
assertIsNone(diffMap.get("tables"));
assertTrue(diffMap.get("tables").getFields().isEmpty());
}
@Test
void diffTableAdded() {
DatabaseMeta original = load("ut/diffsTest/diffTableAdded/original.json");
DatabaseMeta current = load("ut/diffsTest/diffTableAdded/current.json");
// database
RootDiff diff = Diffs.diff(original, current);
assertEquals(DiffType.MODIFIED, diff.getDiffType());
// add table: departments, dept_emp
assertSame(1, diff.getFields().size());
FieldDiff tableField = diff.getFields().iterator().next();
assertEquals("tables", tableField.getFieldName());
assertEquals(DiffType.ADDED, tableField.getDiffType());
// tables without original & current value
assertNull(tableField.getOriginal());
assertNull(tableField.getCurrent());
// add two tables
assertSame(2, tableField.getFields().size());
Map<String, FieldDiff> tableFieldMap = tableField.getFields()
.stream()
.collect(Collectors.toMap(FieldDiff::getFieldName, Function.identity()));
Map<String, TableMeta> currentTablesMap = current.getTables()
.stream()
.collect(Collectors.toMap(TableMeta::getName, Function.identity()));
List.of("departments", "dept_emp").forEach(tableName -> {
assertTrue(tableFieldMap.containsKey(tableName));
FieldDiff departments = tableFieldMap.get(tableName);
assertIsAdded(departments);
assertNull(departments.getOriginal());
assertNotNull(departments.getCurrent());
assertEquals(currentTablesMap.get(tableName), departments.getCurrent());
});
}
@Test
void diffTableRemoved() {
DatabaseMeta original = load("ut/diffsTest/diffTableRemoved/original.json");
DatabaseMeta current = load("ut/diffsTest/diffTableRemoved/current.json");
// database
RootDiff diff = Diffs.diff(original, current);
assertEquals(DiffType.MODIFIED, diff.getDiffType());
// remove table: departments, dept_emp
assertSame(1, diff.getFields().size());
FieldDiff tableField = diff.getFields().iterator().next();
assertEquals("tables", tableField.getFieldName());
assertEquals(DiffType.REMOVED, tableField.getDiffType());
// tables without original & current value
assertNull(tableField.getOriginal());
assertNull(tableField.getCurrent());
// remove two tables
assertSame(2, tableField.getFields().size());
Map<String, FieldDiff> tableFieldMap = tableField.getFields()
.stream()
.collect(Collectors.toMap(FieldDiff::getFieldName, Function.identity()));
Map<String, TableMeta> originalTablesMap = original.getTables()
.stream()
.collect(Collectors.toMap(TableMeta::getName, Function.identity()));
List.of("departments", "dept_emp").forEach(tableName -> {
assertTrue(tableFieldMap.containsKey(tableName));
FieldDiff field = tableFieldMap.get(tableName);
assertIsRemoved(field);
assertNull(field.getCurrent());
assertNotNull(field.getOriginal());
assertEquals(originalTablesMap.get(tableName), field.getOriginal());
});
}
/**
* modify three table: departments, dept_emp
* - dept_manager: add comment, change table type
* - departments: add comment
* - dept_emp: add comment
*/
@Test
void diffTableModified() {
DatabaseMeta original = load("ut/diffsTest/diffTableModified/original.json");
DatabaseMeta current = load("ut/diffsTest/diffTableModified/current.json");
// database
RootDiff diff = Diffs.diff(original, current);
assertEquals(DiffType.MODIFIED, diff.getDiffType());
assertSame(1, diff.getFields().size());
FieldDiff tableField = diff.getFields().iterator().next();
assertEquals("tables", tableField.getFieldName());
assertEquals(DiffType.MODIFIED, tableField.getDiffType());
// tables without original & current value
assertNull(tableField.getOriginal());
assertNull(tableField.getCurrent());
// modify 3 tables
assertSame(3, tableField.getFields().size());
Map<String, FieldDiff> tableFieldMap = tableField.getFields()
.stream()
.collect(Collectors.toMap(FieldDiff::getFieldName, Function.identity()));
Map<String, TableMeta> originalTableMap = original.getTables()
.stream()
.collect(Collectors.toMap(TableMeta::getName, Function.identity()));
Map<String, TableMeta> currentTableMap = current.getTables()
.stream()
.collect(Collectors.toMap(TableMeta::getName, Function.identity()));
List.of("departments", "dept_emp", "dept_manager").forEach(tableName -> {
assertTrue(tableFieldMap.containsKey(tableName));
FieldDiff departments = tableFieldMap.get(tableName);
assertIsModified(departments);
assertNull(departments.getCurrent());
assertNull(departments.getOriginal());
if ("dept_manager".equals(tableName)) {
// columns \ indexes \ triggers \ forgienKes \ comment
assertSame(6, departments.getFields().size());
FieldDiff departmentCommentField = departments.getFields().stream()
.filter(f -> f.getFieldName().equals("type"))
.findAny()
.orElseThrow();
assertEquals(originalTableMap.get(tableName).getType(), departmentCommentField.getOriginal());
assertEquals(currentTableMap.get(tableName).getType(), departmentCommentField.getCurrent());
} else {
// columns \ indexes \ triggers \ forgienKes \ comment
assertSame(5, departments.getFields().size());
}
FieldDiff departmentCommentField = departments.getFields().stream()
.filter(f -> f.getFieldName().equals("comment"))
.findAny()
.orElseThrow();
assertEquals(originalTableMap.get(tableName).getComment(), departmentCommentField.getOriginal());
assertEquals(currentTableMap.get(tableName).getComment(), departmentCommentField.getCurrent());
});
}
/**
* add columns \ indexes \ triggers \ foreignKeys
* <p>
* department:
* - add column [deleted], [dept_code]
* - add index [dept_deleted]
* - add triggers [before_insert]
* - add foreignKeys [dept_emp_ibfk_1]
* </p>
*/
@Test
void diffTableFieldsAdded() {
DatabaseMeta original = load("ut/diffsTest/diffTableFieldsAdded/original.json");
DatabaseMeta current = load("ut/diffsTest/diffTableFieldsAdded/current.json");
// database
RootDiff diff = Diffs.diff(original, current);
assertEquals(DiffType.MODIFIED, diff.getDiffType());
// modified table: departments
assertSame(1, diff.getFields().size());
FieldDiff tableField = diff.getFields().iterator().next();
assertEquals("tables", tableField.getFieldName());
assertEquals(DiffType.MODIFIED, tableField.getDiffType());
// tables without original & current value
assertNull(tableField.getOriginal());
assertNull(tableField.getCurrent());
// modified 1 tables
assertSame(1, tableField.getFields().size());
Map<String, FieldDiff> tableFieldMap = tableField.getFields()
.stream()
.collect(Collectors.toMap(FieldDiff::getFieldName, Function.identity()));
TableMeta currentDepartment = current.getTables()
.stream()
.filter(t -> "departments".equals(t.getName()))
.findFirst()
.orElseThrow();
List.of("departments").forEach(tableName -> {
assertTrue(tableFieldMap.containsKey(tableName));
FieldDiff departments = tableFieldMap.get(tableName);
assertIsModified(departments);
assertNull(departments.getOriginal());
assertNull(departments.getCurrent());
// columns / indexes / triggers / foreignKes
assertSame(4, departments.getFields().size());
for (FieldDiff field : departments.getFields()) {
assertIsModified(field);
if ("columns".equals(field.getFieldName())) {
assertSame(2, field.getFields().size());
for (FieldDiff columnField : field.getFields()) {
assertIsAdded(columnField);
assertNull(columnField.getOriginal());
assertNotNull(columnField.getCurrent());
ColumnMeta colMeta = (ColumnMeta) columnField.getCurrent();
boolean matched = currentDepartment.getColumns().stream()
.anyMatch(idx -> Objects.equals(idx, colMeta));
assertTrue(matched);
}
}
if ("indexes".equals(field.getFieldName())) {
assertSame(1, field.getFields().size());
FieldDiff indexes = field.getFields().iterator().next();
assertIsAdded(indexes);
assertNull(indexes.getOriginal());
IndexMeta index = (IndexMeta) indexes.getCurrent();
assertNotNull(index);
boolean matched = currentDepartment.getIndexes().stream()
.anyMatch(idx -> Objects.equals(idx, index));
assertTrue(matched);
}
if ("triggers".equals(field.getFieldName())) {
assertSame(1, field.getFields().size());
FieldDiff triggers = field.getFields().iterator().next();
assertIsAdded(triggers);
assertNull(triggers.getOriginal());
TriggerMeta tg = (TriggerMeta) triggers.getCurrent();
assertNotNull(tg);
boolean matched = currentDepartment.getTriggers().stream().anyMatch(t -> Objects.equals(t, tg));
assertTrue(matched);
}
if ("foreignKeys".equals(field.getFieldName())) {
assertSame(1, field.getFields().size());
FieldDiff foreignKeys = field.getFields().iterator().next();
assertIsAdded(foreignKeys);
assertNull(foreignKeys.getOriginal());
ForeignKeyMeta fk = (ForeignKeyMeta) foreignKeys.getCurrent();
assertNotNull(fk);
boolean matched = currentDepartment.getForeignKeys().stream().anyMatch(f -> Objects.equals(f, fk));
assertTrue(matched);
}
}
});
}
/**
* dept_emp
* fk: dept_emp_ibfk_2
* column: from_date, to_date
* index: dept_no
* trigger: before_insert
*/
@Test
void diffTableFieldsRemoved() {
DatabaseMeta original = load("ut/diffsTest/diffTableFieldsRemoved/original.json");
DatabaseMeta current = load("ut/diffsTest/diffTableFieldsRemoved/current.json");
// database
RootDiff diff = Diffs.diff(original, current);
assertEquals(DiffType.MODIFIED, diff.getDiffType());
// modified table: departments
assertSame(1, diff.getFields().size());
FieldDiff tableField = diff.getFields().iterator().next();
assertEquals("tables", tableField.getFieldName());
assertEquals(DiffType.MODIFIED, tableField.getDiffType());
// tables without original & current value
assertNull(tableField.getOriginal());
assertNull(tableField.getCurrent());
// modified 1 tables
assertSame(1, tableField.getFields().size());
Map<String, FieldDiff> tableFieldMap = tableField.getFields()
.stream()
.collect(Collectors.toMap(FieldDiff::getFieldName, Function.identity()));
TableMeta originalTable = original.getTables()
.stream()
.filter(t -> "dept_emp".equals(t.getName()))
.findFirst()
.orElseThrow();
List.of("dept_emp").forEach(tableName -> {
assertTrue(tableFieldMap.containsKey(tableName));
FieldDiff departments = tableFieldMap.get(tableName);
assertIsModified(departments);
assertNull(departments.getOriginal());
assertNull(departments.getCurrent());
// columns / indexes / triggers / foreignKes
assertSame(4, departments.getFields().size());
for (FieldDiff field : departments.getFields()) {
assertIsModified(field);
if ("columns".equals(field.getFieldName())) {
assertSame(2, field.getFields().size());
for (FieldDiff columnField : field.getFields()) {
assertIsRemoved(columnField);
assertNull(columnField.getCurrent());
assertNotNull(columnField.getOriginal());
ColumnMeta colMeta = (ColumnMeta) columnField.getOriginal();
boolean matched = originalTable.getColumns().stream()
.anyMatch(idx -> Objects.equals(idx, colMeta));
assertTrue(matched);
}
}
if ("indexes".equals(field.getFieldName())) {
assertSame(1, field.getFields().size());
FieldDiff indexes = field.getFields().iterator().next();
assertIsRemoved(indexes);
assertNull(indexes.getCurrent());
IndexMeta index = (IndexMeta) indexes.getOriginal();
assertNotNull(index);
boolean matched = originalTable.getIndexes().stream()
.anyMatch(idx -> Objects.equals(idx, index));
assertTrue(matched);
}
if ("triggers".equals(field.getFieldName())) {
assertSame(1, field.getFields().size());
FieldDiff triggers = field.getFields().iterator().next();
assertIsRemoved(triggers);
assertNull(triggers.getCurrent());
TriggerMeta tg = (TriggerMeta) triggers.getOriginal();
assertNotNull(tg);
boolean matched = originalTable.getTriggers().stream().anyMatch(t -> Objects.equals(t, tg));
assertTrue(matched);
}
if ("foreignKeys".equals(field.getFieldName())) {
assertSame(1, field.getFields().size());
FieldDiff foreignKeys = field.getFields().iterator().next();
assertIsRemoved(foreignKeys);
assertNull(foreignKeys.getCurrent());
ForeignKeyMeta fk = (ForeignKeyMeta) foreignKeys.getOriginal();
assertNotNull(fk);
boolean matched = originalTable.getForeignKeys().stream().anyMatch(f -> Objects.equals(f, fk));
assertTrue(matched);
}
}
});
}
/**
* departments
* column: dept_no add comment
* column: dept_name add comment
* indexes: dept_name change unique=false
* <p>
* dept_emp
* column: emp_no change default value
* column: dept_noL change auto increment true
* indexes: dept_no
* triggers: before_insert
* foreignKeys: dept_emp_ibfk_2
* </p>
*/
@Test
void diffTableFieldsModified() {
DatabaseMeta original = load("ut/diffsTest/diffTableFieldsModified/original.json");
DatabaseMeta current = load("ut/diffsTest/diffTableFieldsModified/current.json");
// database
RootDiff diff = Diffs.diff(original, current);
assertEquals(DiffType.MODIFIED, diff.getDiffType());
// modified table: departments, dept_emp
assertSame(1, diff.getFields().size());
FieldDiff tablesField = diff.getFields().iterator().next();
assertEquals("tables", tablesField.getFieldName());
assertEquals(DiffType.MODIFIED, tablesField.getDiffType());
// tables without original & current value
assertNull(tablesField.getOriginal());
assertNull(tablesField.getCurrent());
// modified 1 tables
assertSame(2, tablesField.getFields().size());
Map<String, FieldDiff> tableFieldMap = tablesField.getFields()
.stream()
.collect(Collectors.toMap(FieldDiff::getFieldName, Function.identity()));
Map<String, TableMeta> originalTaleMap = original.getTables()
.stream()
.collect(Collectors.toMap(TableMeta::getName, Function.identity()));
Map<String, TableMeta> currentTableMap = current.getTables()
.stream()
.collect(Collectors.toMap(TableMeta::getName, Function.identity()));
List.of("departments", "dept_emp").forEach(tableName -> {
assertTrue(tableFieldMap.containsKey(tableName));
FieldDiff tableField = tableFieldMap.get(tableName);
assertIsModified(tableField);
assertNull(tableField.getOriginal());
assertNull(tableField.getCurrent());
// columns / indexes / triggers / foreignKes
assertSame(4, tableField.getFields().size());
for (FieldDiff field : tableField.getFields()) {
if ("columns".equals(field.getFieldName())) {
assertIsModified(field);
assertSame(2, field.getFields().size());
for (FieldDiff columnField : field.getFields()) {
assertIsModified(columnField);
assertNotNull(columnField.getCurrent());
assertNotNull(columnField.getOriginal());
ColumnMeta originalCol = (ColumnMeta) columnField.getOriginal();
boolean matched = originalTaleMap.get(tableName)
.getColumns()
.stream()
.anyMatch(idx -> Objects.equals(idx, originalCol));
assertTrue(matched);
ColumnMeta currentCol = (ColumnMeta) columnField.getCurrent();
assertTrue(currentTableMap.get(tableName)
.getColumns()
.stream()
.anyMatch(idx -> Objects.equals(idx, currentCol)));
}
}
if ("indexes".equals(field.getFieldName())) {
assertIsModified(field);
assertSame(1, field.getFields().size());
FieldDiff indexes = field.getFields().iterator().next();
assertIsModified(indexes);
assertNotNull(indexes.getCurrent());
assertNotNull(indexes.getOriginal());
IndexMeta originalIndex = (IndexMeta) indexes.getOriginal();
boolean matched = originalTaleMap.get(tableName)
.getIndexes()
.stream()
.anyMatch(idx -> Objects.equals(idx, originalIndex));
assertTrue(matched);
IndexMeta currentIndex = (IndexMeta) indexes.getCurrent();
assertTrue(currentTableMap.get(tableName)
.getIndexes()
.stream()
.anyMatch(idx -> Objects.equals(idx, currentIndex)));
}
if (tableName.equals("dept_emp") && "triggers".equals(field.getFieldName())) {
assertIsModified(field);
assertSame(1, field.getFields().size());
FieldDiff triggers = field.getFields().iterator().next();
assertIsModified(triggers);
assertNotNull(triggers.getCurrent());
assertNotNull(triggers.getOriginal());
TriggerMeta originalTg = (TriggerMeta) triggers.getOriginal();
assertTrue(originalTaleMap.get(tableName).getTriggers().stream()
.anyMatch(t -> Objects.equals(t, originalTg)));
TriggerMeta currentTg = (TriggerMeta) triggers.getCurrent();
assertTrue(currentTableMap.get(tableName).getTriggers().stream()
.anyMatch(t -> Objects.equals(t, currentTg)));
}
if (tableName.equals("dept_emp") && "foreignKeys".equals(field.getFieldName())) {
assertIsModified(field);
assertSame(1, field.getFields().size());
FieldDiff foreignKeys = field.getFields().iterator().next();
assertIsModified(foreignKeys);
assertNotNull(foreignKeys.getCurrent());
assertNotNull(foreignKeys.getOriginal());
ForeignKeyMeta originalFk = (ForeignKeyMeta) foreignKeys.getOriginal();
assertTrue(originalTaleMap.get(tableName)
.getForeignKeys().stream().anyMatch(f -> Objects.equals(f, originalFk)));
ForeignKeyMeta currentFk = (ForeignKeyMeta) foreignKeys.getCurrent();
assertTrue(currentTableMap.get(tableName)
.getForeignKeys().stream().anyMatch(f -> Objects.equals(f, currentFk)));
}
if (tableName.equals("departments")
&& List.of("foreignKeys", "triggers").contains(field.getFieldName())) {
assertIsNone(field);
}
}
});
}
private void assertIsModified(FieldDiff diff) {
assertEquals(DiffType.MODIFIED, diff.getDiffType());
}
private void assertIsNone(FieldDiff diff) {
assertEquals(DiffType.NONE, diff.getDiffType());
}
private void assertIsRemoved(FieldDiff diff) {
assertEquals(DiffType.REMOVED, diff.getDiffType());
}
private void assertIsAdded(FieldDiff diff) {
assertEquals(DiffType.ADDED, diff.getDiffType());
}
private DatabaseMeta load(String url) {
URL originalUrl = Thread.currentThread().getContextClassLoader()
.getResource(url);
try {
return objectMapper.readValue(originalUrl, DatabaseMeta.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

466
plugin/src/test/resources/ut/diffsTest/diffDatabaseAdded/current.json

@ -0,0 +1,466 @@
{
"tables": [
{
"name": "departments",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_name",
"type": "VARCHAR",
"size": 40,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_name",
"isUniqueKey": true,
"columnNames": [
"dept_name"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"dept_no"
]
}
],
"foreignKeys": [],
"triggers": []
},
{
"name": "dept_emp",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_no",
"isUniqueKey": false,
"columnNames": [
"dept_no"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"dept_no"
]
}
],
"foreignKeys": [
{
"fkName": "dept_emp_ibfk_2",
"fkTableName": "dept_emp",
"fkColumnName": "dept_no",
"pkName": "PRIMARY",
"pkTableName": "departments",
"pkColumnName": "dept_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
},
{
"fkName": "dept_emp_ibfk_1",
"fkTableName": "dept_emp",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "dept_manager",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_no",
"isUniqueKey": false,
"columnNames": [
"dept_no"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"dept_no"
]
}
],
"foreignKeys": [
{
"fkName": "dept_manager_ibfk_2",
"fkTableName": "dept_manager",
"fkColumnName": "dept_no",
"pkName": "PRIMARY",
"pkTableName": "departments",
"pkColumnName": "dept_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
},
{
"fkName": "dept_manager_ibfk_1",
"fkTableName": "dept_manager",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "employees",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "birth_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "first_name",
"type": "VARCHAR",
"size": 14,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "last_name",
"type": "VARCHAR",
"size": 16,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "gender",
"type": "ENUM",
"size": 1,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "hire_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no"
]
}
],
"foreignKeys": [],
"triggers": []
},
{
"name": "salaries",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "salary",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"from_date"
]
}
],
"foreignKeys": [
{
"fkName": "salaries_ibfk_1",
"fkTableName": "salaries",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "titles",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "title",
"type": "VARCHAR",
"size": 50,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "YES",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"title",
"from_date"
]
}
],
"foreignKeys": [
{
"fkName": "titles_ibfk_1",
"fkTableName": "titles",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
}
]
}

3
plugin/src/test/resources/ut/diffsTest/diffDatabaseAdded/original.json

@ -0,0 +1,3 @@
{
}

470
plugin/src/test/resources/ut/diffsTest/diffDatabaseModified/current.json

@ -0,0 +1,470 @@
{
"databaseName": "employees",
"schemaName": "employees",
"productName": "MySQL",
"productVersion": "8.0.26",
"tables": [
{
"name": "departments",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_name",
"type": "VARCHAR",
"size": 40,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_name",
"isUniqueKey": true,
"columnNames": [
"dept_name"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"dept_no"
]
}
],
"foreignKeys": [],
"triggers": []
},
{
"name": "dept_emp",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_no",
"isUniqueKey": false,
"columnNames": [
"dept_no"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"dept_no"
]
}
],
"foreignKeys": [
{
"fkName": "dept_emp_ibfk_2",
"fkTableName": "dept_emp",
"fkColumnName": "dept_no",
"pkName": "PRIMARY",
"pkTableName": "departments",
"pkColumnName": "dept_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
},
{
"fkName": "dept_emp_ibfk_1",
"fkTableName": "dept_emp",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "dept_manager",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_no",
"isUniqueKey": false,
"columnNames": [
"dept_no"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"dept_no"
]
}
],
"foreignKeys": [
{
"fkName": "dept_manager_ibfk_2",
"fkTableName": "dept_manager",
"fkColumnName": "dept_no",
"pkName": "PRIMARY",
"pkTableName": "departments",
"pkColumnName": "dept_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
},
{
"fkName": "dept_manager_ibfk_1",
"fkTableName": "dept_manager",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "employees",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "birth_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "first_name",
"type": "VARCHAR",
"size": 14,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "last_name",
"type": "VARCHAR",
"size": 16,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "gender",
"type": "ENUM",
"size": 1,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "hire_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no"
]
}
],
"foreignKeys": [],
"triggers": []
},
{
"name": "salaries",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "salary",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"from_date"
]
}
],
"foreignKeys": [
{
"fkName": "salaries_ibfk_1",
"fkTableName": "salaries",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "titles",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "title",
"type": "VARCHAR",
"size": 50,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "YES",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"title",
"from_date"
]
}
],
"foreignKeys": [
{
"fkName": "titles_ibfk_1",
"fkTableName": "titles",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
}
]
}

470
plugin/src/test/resources/ut/diffsTest/diffDatabaseModified/original.json

@ -0,0 +1,470 @@
{
"databaseName": "employees",
"schemaName": "employees",
"productName": "MySQL",
"productVersion": "9.0",
"tables": [
{
"name": "departments",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_name",
"type": "VARCHAR",
"size": 40,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_name",
"isUniqueKey": true,
"columnNames": [
"dept_name"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"dept_no"
]
}
],
"foreignKeys": [],
"triggers": []
},
{
"name": "dept_emp",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_no",
"isUniqueKey": false,
"columnNames": [
"dept_no"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"dept_no"
]
}
],
"foreignKeys": [
{
"fkName": "dept_emp_ibfk_2",
"fkTableName": "dept_emp",
"fkColumnName": "dept_no",
"pkName": "PRIMARY",
"pkTableName": "departments",
"pkColumnName": "dept_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
},
{
"fkName": "dept_emp_ibfk_1",
"fkTableName": "dept_emp",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "dept_manager",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_no",
"isUniqueKey": false,
"columnNames": [
"dept_no"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"dept_no"
]
}
],
"foreignKeys": [
{
"fkName": "dept_manager_ibfk_2",
"fkTableName": "dept_manager",
"fkColumnName": "dept_no",
"pkName": "PRIMARY",
"pkTableName": "departments",
"pkColumnName": "dept_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
},
{
"fkName": "dept_manager_ibfk_1",
"fkTableName": "dept_manager",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "employees",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "birth_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "first_name",
"type": "VARCHAR",
"size": 14,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "last_name",
"type": "VARCHAR",
"size": 16,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "gender",
"type": "ENUM",
"size": 1,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "hire_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no"
]
}
],
"foreignKeys": [],
"triggers": []
},
{
"name": "salaries",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "salary",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"from_date"
]
}
],
"foreignKeys": [
{
"fkName": "salaries_ibfk_1",
"fkTableName": "salaries",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "titles",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "title",
"type": "VARCHAR",
"size": 50,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "YES",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"title",
"from_date"
]
}
],
"foreignKeys": [
{
"fkName": "titles_ibfk_1",
"fkTableName": "titles",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
}
]
}

3
plugin/src/test/resources/ut/diffsTest/diffDatabaseRemoved/current.json

@ -0,0 +1,3 @@
{
}

466
plugin/src/test/resources/ut/diffsTest/diffDatabaseRemoved/original.json

@ -0,0 +1,466 @@
{
"tables": [
{
"name": "departments",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_name",
"type": "VARCHAR",
"size": 40,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_name",
"isUniqueKey": true,
"columnNames": [
"dept_name"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"dept_no"
]
}
],
"foreignKeys": [],
"triggers": []
},
{
"name": "dept_emp",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_no",
"isUniqueKey": false,
"columnNames": [
"dept_no"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"dept_no"
]
}
],
"foreignKeys": [
{
"fkName": "dept_emp_ibfk_2",
"fkTableName": "dept_emp",
"fkColumnName": "dept_no",
"pkName": "PRIMARY",
"pkTableName": "departments",
"pkColumnName": "dept_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
},
{
"fkName": "dept_emp_ibfk_1",
"fkTableName": "dept_emp",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "dept_manager",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_no",
"isUniqueKey": false,
"columnNames": [
"dept_no"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"dept_no"
]
}
],
"foreignKeys": [
{
"fkName": "dept_manager_ibfk_2",
"fkTableName": "dept_manager",
"fkColumnName": "dept_no",
"pkName": "PRIMARY",
"pkTableName": "departments",
"pkColumnName": "dept_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
},
{
"fkName": "dept_manager_ibfk_1",
"fkTableName": "dept_manager",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "employees",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "birth_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "first_name",
"type": "VARCHAR",
"size": 14,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "last_name",
"type": "VARCHAR",
"size": 16,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "gender",
"type": "ENUM",
"size": 1,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "hire_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no"
]
}
],
"foreignKeys": [],
"triggers": []
},
{
"name": "salaries",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "salary",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"from_date"
]
}
],
"foreignKeys": [
{
"fkName": "salaries_ibfk_1",
"fkTableName": "salaries",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "titles",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "title",
"type": "VARCHAR",
"size": 50,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "YES",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"title",
"from_date"
]
}
],
"foreignKeys": [
{
"fkName": "titles_ibfk_1",
"fkTableName": "titles",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
}
]
}

466
plugin/src/test/resources/ut/diffsTest/diffDatabaseSame/current.json

@ -0,0 +1,466 @@
{
"tables": [
{
"name": "departments",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_name",
"type": "VARCHAR",
"size": 40,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_name",
"isUniqueKey": true,
"columnNames": [
"dept_name"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"dept_no"
]
}
],
"foreignKeys": [],
"triggers": []
},
{
"name": "dept_emp",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_no",
"isUniqueKey": false,
"columnNames": [
"dept_no"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"dept_no"
]
}
],
"foreignKeys": [
{
"fkName": "dept_emp_ibfk_2",
"fkTableName": "dept_emp",
"fkColumnName": "dept_no",
"pkName": "PRIMARY",
"pkTableName": "departments",
"pkColumnName": "dept_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
},
{
"fkName": "dept_emp_ibfk_1",
"fkTableName": "dept_emp",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "dept_manager",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "dept_no",
"type": "CHAR",
"size": 4,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "dept_no",
"isUniqueKey": false,
"columnNames": [
"dept_no"
]
},
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"dept_no"
]
}
],
"foreignKeys": [
{
"fkName": "dept_manager_ibfk_2",
"fkTableName": "dept_manager",
"fkColumnName": "dept_no",
"pkName": "PRIMARY",
"pkTableName": "departments",
"pkColumnName": "dept_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
},
{
"fkName": "dept_manager_ibfk_1",
"fkTableName": "dept_manager",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "employees",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "birth_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "first_name",
"type": "VARCHAR",
"size": 14,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "last_name",
"type": "VARCHAR",
"size": 16,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "gender",
"type": "ENUM",
"size": 1,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "hire_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no"
]
}
],
"foreignKeys": [],
"triggers": []
},
{
"name": "salaries",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "salary",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"from_date"
]
}
],
"foreignKeys": [
{
"fkName": "salaries_ibfk_1",
"fkTableName": "salaries",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
},
{
"name": "titles",
"type": "TABLE",
"comment": "",
"columns": [
{
"name": "emp_no",
"type": "INT",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "title",
"type": "VARCHAR",
"size": 50,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "from_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": true,
"nullable": "NO",
"autoIncrement": "NO",
"defaultValue": null
},
{
"name": "to_date",
"type": "DATE",
"size": 10,
"decimalDigits": null,
"comment": "",
"isPrimaryKey": false,
"nullable": "YES",
"autoIncrement": "NO",
"defaultValue": null
}
],
"indexes": [
{
"name": "PRIMARY",
"isUniqueKey": true,
"columnNames": [
"emp_no",
"title",
"from_date"
]
}
],
"foreignKeys": [
{
"fkName": "titles_ibfk_1",
"fkTableName": "titles",
"fkColumnName": "emp_no",
"pkName": "PRIMARY",
"pkTableName": "employees",
"pkColumnName": "emp_no",
"updateRule": "CASCADE",
"deleteRule": "CASCADE"
}
],
"triggers": []
}
]
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save