11<!DOCTYPE html>
22< html >
3- < title > sqldef</ title >
3+ < title > sqldef.github.io </ title >
44 < link href ="https://fonts.googleapis.com/css?family=Raleway&display=swap " rel ="stylesheet ">
55 < head >
66 < meta charset ="utf-8 ">
2020 background : # eee ;
2121 color : # 000 ;
2222 padding : 20px ;
23+ }
24+ textarea {
2325 width : 100% ;
26+ box-sizing : border-box;
2427 }
2528 pre {
2629 display : none;
30+ width : 100% ;
31+ box-sizing : border-box;
2732 }
28- # error {
33+ . error {
2934 padding : 1em ;
3035 background : IndianRed;
3136 color : DarkRed;
3944 }
4045 h4 .schema-header {
4146 margin-bottom : 0.7em ;
47+ margin-top : 1em ;
48+ }
49+ .schema-row {
50+ display : flex;
51+ gap : 20px ;
52+ margin-bottom : 20px ;
53+ }
54+ .schema-pane {
55+ flex : 1 ;
56+ }
57+ .diff-section {
58+ margin-bottom : 20px ;
59+ }
60+ .diff-label {
61+ font-weight : bold;
62+ margin-bottom : 0.5em ;
63+ }
64+ select {
65+ font-size : 18px ;
66+ padding : 8px ;
67+ margin-bottom : 20px ;
68+ }
69+ footer {
70+ margin-top : 100px ;
71+ text-align : center;
4272 }
4373 </ style >
4474 </ head >
4575 < body >
4676 < h1 > sqldef</ h1 >
47- < img src ="https://github.com/k0kubun/ sqldef/raw/master/demo.gif " alt =" screen capture " />
48-
49- < h2 > What is it? </ h2 >
50- < p > sqldef is a < a href =" https://github.com/k0kubun/sqldef " > CLI tool </ a > , < a href =" https://github.com/sqldef/sqldef.github.io " > webasm library </ a > , and < a href =" https://github.com/sqldef/node-sqldef " > nodejs tool/library </ a > for diffing SQL schema. You can use it to manage migration of PostgreSQL and MySQL databases, using regular SQL DDL .</ p >
77+ < p > sqldef is a < a href ="https://github.com/sqldef/sqldef " > CLI tool </ a > , < a
78+ href =" https://github.com/sqldef/sqldef.github.io " > Wasm library </ a > , and < a
79+ href =" https://github.com/sqldef/node-sqldef " > nodejs tool/library </ a > for diffing two SQL schemas. You can use it to
80+ manage migration of PostgreSQL, MySQL, SQLite3 , and SQL Server databases, using regular SQL DDLs .</ p >
5181
5282 < h2 > Demo</ h2 >
5383 < p > You can generate DDLs to update the DB schema:</ p >
@@ -56,50 +86,141 @@ <h2>Demo</h2>
5686 < select id ="dbType ">
5787 < option value ="mysql "> MySQL</ option >
5888 < option value ="postgres "> PostgreSQL</ option >
89+ < option value ="sqlite3 "> SQLite3</ option >
90+ < option value ="mssql "> SQL Server</ option >
5991 </ select >
60- < button id ="buttonDiff "> DIFF</ button >
6192 </ div >
6293
63- < pre id ="output "> </ pre >
64- < pre id ="error "> </ pre >
65-
66- < h4 class ="schema-header "> Current schema</ h4 >
67- < textarea id ="inputA " rows ="10 ">
68- CREATE TABLE user (
94+ < div class ="schema-row ">
95+ < div class ="schema-pane ">
96+ < h4 class ="schema-header "> Current schema</ h4 >
97+ < textarea id ="inputA " rows ="10 "> CREATE TABLE users (
6998 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
7099 name VARCHAR(128) DEFAULT 'konsumer'
71- ) Engine=InnoDB DEFAULT CHARSET=utf8mb4;
72- </ textarea >
73-
74- < h4 class ="schema-header "> New schema</ h4 >
75- < textarea id ="inputB " rows ="10 ">
76- CREATE TABLE user (
100+ ) Engine=InnoDB DEFAULT CHARSET=utf8mb4;</ textarea >
101+ </ div >
102+ < div class ="schema-pane ">
103+ < h4 class ="schema-header "> Desired schema</ h4 >
104+ < textarea id ="inputB " rows ="10 "> CREATE TABLE users (
77105 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
78106 name VARCHAR(128) DEFAULT 'konsumer',
79107 created_at DATETIME NOT NULL
80- ) Engine=InnoDB DEFAULT CHARSET=utf8mb4;
81- </ textarea >
108+ ) Engine=InnoDB DEFAULT CHARSET=utf8mb4;</ textarea >
109+ </ div >
110+ </ div >
111+
112+ < div class ="diff-section ">
113+ < div class ="diff-label "> Up (current → desired)</ div >
114+ < pre id ="outputUp "> </ pre >
115+ < pre id ="errorUp " class ="error "> </ pre >
116+ </ div >
117+
118+ < div class ="diff-section ">
119+ < div class ="diff-label "> Down (desired → current)</ div >
120+ < pre id ="outputDown "> </ pre >
121+ < pre id ="errorDown " class ="error "> </ pre >
122+ </ div >
82123
83124< script >
84- const button = document . getElementById ( 'buttonDiff' )
85125const dbType = document . getElementById ( 'dbType' )
86126const inputA = document . getElementById ( 'inputA' )
87127const inputB = document . getElementById ( 'inputB' )
88- const output = document . getElementById ( 'output' )
89- const error = document . getElementById ( 'error' )
128+ const outputUp = document . getElementById ( 'outputUp' )
129+ const errorUp = document . getElementById ( 'errorUp' )
130+ const outputDown = document . getElementById ( 'outputDown' )
131+ const errorDown = document . getElementById ( 'errorDown' )
90132
91- button . addEventListener ( 'click' , async ( ) => {
92- output . style . display = 'none'
93- error . style . display = 'none'
133+ const schemaExamples = {
134+ mysql : {
135+ current : `CREATE TABLE users (
136+ id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
137+ name VARCHAR(128) DEFAULT 'konsumer'
138+ ) Engine=InnoDB DEFAULT CHARSET=utf8mb4;` ,
139+ desired : `CREATE TABLE users (
140+ id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
141+ name VARCHAR(128) DEFAULT 'konsumer',
142+ created_at DATETIME NOT NULL
143+ ) Engine=InnoDB DEFAULT CHARSET=utf8mb4;`
144+ } ,
145+ postgres : {
146+ current : `CREATE TABLE users (
147+ id BIGSERIAL PRIMARY KEY,
148+ name VARCHAR(128) DEFAULT 'konsumer'
149+ );` ,
150+ desired : `CREATE TABLE users (
151+ id BIGSERIAL PRIMARY KEY,
152+ name VARCHAR(128) DEFAULT 'konsumer',
153+ created_at TIMESTAMP NOT NULL
154+ );`
155+ } ,
156+ sqlite3 : {
157+ current : `CREATE TABLE users (
158+ id INTEGER PRIMARY KEY AUTOINCREMENT,
159+ name TEXT DEFAULT 'konsumer'
160+ );` ,
161+ desired : `CREATE TABLE users (
162+ id INTEGER PRIMARY KEY AUTOINCREMENT,
163+ name TEXT DEFAULT 'konsumer',
164+ created_at TEXT NOT NULL
165+ );`
166+ } ,
167+ mssql : {
168+ current : `CREATE TABLE users (
169+ id BIGINT IDENTITY(1,1) PRIMARY KEY,
170+ name NVARCHAR(128) DEFAULT 'konsumer'
171+ );` ,
172+ desired : `CREATE TABLE users (
173+ id BIGINT IDENTITY(1,1) PRIMARY KEY,
174+ name NVARCHAR(128) DEFAULT 'konsumer',
175+ created_at DATETIME NOT NULL
176+ );`
177+ }
178+ }
179+
180+ async function runDiff ( ) {
181+ // Run up diff (current -> desired)
182+ outputUp . style . display = 'none'
183+ errorUp . style . display = 'none'
184+ try {
185+ const result = await window . sqldef ( dbType . value , inputB . value , inputA . value )
186+ outputUp . innerHTML = result
187+ outputUp . style . display = 'block'
188+ } catch ( e ) {
189+ errorUp . style . display = 'block'
190+ errorUp . innerHTML = e . message
191+ }
192+
193+ // Run down diff (desired -> current)
194+ outputDown . style . display = 'none'
195+ errorDown . style . display = 'none'
94196 try {
95- output . innerHTML = await window . sqldef ( dbType . value , inputB . value , inputA . value )
96- output . style . display = 'block'
197+ const result = await window . sqldef ( dbType . value , inputA . value , inputB . value )
198+ outputDown . innerHTML = result
199+ outputDown . style . display = 'block'
97200 } catch ( e ) {
98- error . style . display = 'block'
99- error . innerHTML = e . message
201+ errorDown . style . display = 'block'
202+ errorDown . innerHTML = e . message
100203 }
204+ }
205+
206+ dbType . addEventListener ( 'change' , ( ) => {
207+ const examples = schemaExamples [ dbType . value ]
208+ if ( examples ) {
209+ inputA . value = examples . current
210+ inputB . value = examples . desired
211+ }
212+ runDiff ( )
101213} )
214+
215+ inputA . addEventListener ( 'input' , runDiff )
216+ inputB . addEventListener ( 'input' , runDiff )
217+
218+ // Run diff on initial load
219+ runDiff ( )
102220</ script >
103221
222+ < footer >
223+ < p > < a href ="https://github.com/sqldef "> https://github.com/sqldef</ a > </ p >
224+ </ footer >
104225 </ body >
105226</ html >
0 commit comments