Repository: ariga/atlas
Pull request #2024 (2023-08-26 04:44:47)

doc/md: update SQLServer URL example


Patch:
diff --git a/README.md b/README.md
index c9273197..eff3d976 100644
--- a/README.md
+++ b/README.md
@@ -262,7 +262,7 @@ Atlas offers additional commands to assist users managing their database migrati
 `migrate status`, and more. For more information, see the versioned migration documentation at https://atlasgo.io/versioned/diff.
 
 ### Supported databases
-MySQL, MariaDB, PostgresSQL, SQLite, TiDB, CockroachDB
+MySQL, MariaDB, PostgresSQL, SQLite, TiDB, CockroachDB, SQL Server.
 
 [HCL]: https://atlasgo.io/atlas-schema/hcl
 [SQL]: https://atlasgo.io/atlas-schema/sql
diff --git a/cmd/atlas/internal/cmdlog/cmdlog.go b/cmd/atlas/internal/cmdlog/cmdlog.go
index 07a1ca21..4e5cbeed 100644
--- a/cmd/atlas/internal/cmdlog/cmdlog.go
+++ b/cmd/atlas/internal/cmdlog/cmdlog.go
@@ -550,10 +550,16 @@ func (s *SchemaInspect) MarshalHCL() (string, error) {
 // MarshalJSON implements json.Marshaler.
 func (s *SchemaInspect) MarshalJSON() ([]byte, error) {
 	type (
+		Attrs struct {
+			Comment string `json:"comment,omitempty"`
+			Charset string `json:"charset,omitempty"`
+			Collate string `json:"collate,omitempty"`
+		}
 		Column struct {
 			Name string `json:"name"`
 			Type string `json:"type,omitempty"`
 			Null bool   `json:"null,omitempty"`
+			Attrs
 		}
 		IndexPart struct {
 			Desc   bool   `json:"desc,omitempty"`
@@ -579,25 +585,45 @@ func (s *SchemaInspect) MarshalJSON() ([]byte, error) {
 			Indexes     []Index      `json:"indexes,omitempty"`
 			PrimaryKey  *Index       `json:"primary_key,omitempty"`
 			ForeignKeys []ForeignKey `json:"foreign_keys,omitempty"`
+			Attrs
 		}
 		Schema struct {
 			Name   string  `json:"name"`
 			Tables []Table `json:"tables,omitempty"`
+			Attrs
+		}
+	)
+	var (
+		realm struct {
+			Schemas []Schema `json:"schemas,omitempty"`
+		}
+		setAttrs = func(from []schema.Attr, to *Attrs) {
+			for i := range from {
+				switch a := from[i].(type) {
+				case *schema.Comment:
+					to.Comment = a.Text
+				case *schema.Charset:
+					to.Charset = a.V
+				case *schema.Collation:
+					to.Collate = a.V
+				}
+			}
 		}
 	)
-	var realm struct {
-		Schemas []Schema `json:"schemas,omitempty"`
-	}
 	for _, s1 := range s.Realm.Schemas {
 		s2 := Schema{Name: s1.Name}
+		setAttrs(s1.Attrs, &s2.Attrs)
 		for _, t1 := range s1.Tables {
 			t2 := Table{Name: t1.Name}
+			setAttrs(t1.Attrs, &t2.Attrs)
 			for _, c1 := range t1.Columns {
-				t2.Columns = append(t2.Columns, Column{
+				c2 := Column{
 					Name: c1.Name,
 					Type: c1.Type.Raw,
 					Null: c1.Type.Null,
-				})
+				}
+				setAttrs(c1.Attrs, &c2.Attrs)
+				t2.Columns = append(t2.Columns, c2)
 			}
 			idxParts := func(idx *schema.Index) (parts []IndexPart) {
 				for _, p1 := range idx.Parts {
diff --git a/doc/md/concepts/url.mdx b/doc/md/concepts/url.mdx
index 0501d692..94110656 100644
--- a/doc/md/concepts/url.mdx
+++ b/doc/md/concepts/url.mdx
@@ -24,6 +24,7 @@ values={[
 {label: 'MySQL', value: 'mysql'},
 {label: 'MariaDB', value: 'maria'},
 {label: 'PostgreSQL', value: 'postgres'},
+{label: 'SQLServer', value: 'sqlserver'},
 {label: 'SQLite', value: 'sqlite'},
 {label: 'Docker', value: 'docker'},
 ]}>
@@ -88,6 +89,23 @@ Connecting to a local PostgreSQL with credentials and SSL disabled:
 postgres://postgres:pass@0.0.0.0:5432/database?search_path=public&sslmode=disable
 ```
 
+</TabItem>
+<TabItem value="sqlserver">
+
+Connecting to a default schema of current user:
+```shell
+sqlserver://sa:P@ssw0rd0995@localhost:1433?database=master&mode=schema
+```
+
+Connecting to a local SQLServer database named `master` (all schemas). The user need to have `db_owner` role:
+```shell
+sqlserver://sa:P@ssw0rd0995@localhost:1433?database=master&mode=database
+```
+
+:::note
+- The `mode` parameter is Atlas-specific and isn't used for opening the underlying connection.
+- The default `mode` is `schema`.
+:::
 </TabItem>
 <TabItem value="sqlite">
 
diff --git a/doc/website/docusaurus.config.js b/doc/website/docusaurus.config.js
index 681991b4..be126ac2 100644
--- a/doc/website/docusaurus.config.js
+++ b/doc/website/docusaurus.config.js
@@ -9,7 +9,7 @@ module.exports = {
   organizationName: 'ariga',
   projectName: 'atlas',
   themeConfig: {
-    image: "https://atlas-og-img.vercel.app/**Atlas%20%7C**%20Open-source%20database%20schema%20management.png?theme=dark",
+    image: "https://og.atlasgo.io/image?title=Schema%20Migration%20Tool%20for%20any%20Language",
     prism: {
       additionalLanguages: ['hcl'],
       magicComments: [
diff --git a/sql/mysql/inspect.go b/sql/mysql/inspect.go
index 4561ea2a..2c785468 100644
--- a/sql/mysql/inspect.go
+++ b/sql/mysql/inspect.go
@@ -451,6 +451,9 @@ func (i *inspect) checks(ctx context.Context, s *schema.Schema) error {
 				// Unset the inspected CHARSET/COLLATE attributes
 				// as they are valid only for character types.
 				c.UnsetCharset().UnsetCollation()
+				// Skip adding this CHECK constraint to the table definition
+				// as it is implicitly created by MariaDB for this JSON column.
+				continue
 			}
 		} else if enforced.String == "NO" {
 			// The ENFORCED attribute is not supported by MariaDB.


Test patch:
diff --git a/cmd/atlas/internal/cmdlog/cmdlog_test.go b/cmd/atlas/internal/cmdlog/cmdlog_test.go
index 2cef48b8..459085b1 100644
--- a/cmd/atlas/internal/cmdlog/cmdlog_test.go
+++ b/cmd/atlas/internal/cmdlog/cmdlog_test.go
@@ -26,8 +26,10 @@ func TestSchemaInspect_MarshalJSON(t *testing.T) {
 	report := &cmdlog.SchemaInspect{
 		Realm: schema.NewRealm(
 			schema.New("test").
+				SetComment("schema comment").
 				AddTables(
 					schema.NewTable("users").
+						SetCharset("charset").
 						AddColumns(
 							&schema.Column{
 								Name: "id",
@@ -36,6 +38,9 @@ func TestSchemaInspect_MarshalJSON(t *testing.T) {
 							&schema.Column{
 								Name: "name",
 								Type: &schema.ColumnType{Raw: "varchar(255)"},
+								Attrs: []schema.Attr{
+									&schema.Collation{V: "collate"},
+								},
 							},
 						),
 					schema.NewTable("posts").
@@ -71,9 +76,11 @@ func TestSchemaInspect_MarshalJSON(t *testing.T) {
             },
             {
               "name": "name",
-              "type": "varchar(255)"
+              "type": "varchar(255)",
+              "collate": "collate"
             }
-          ]
+          ],
+          "charset": "charset"
         },
         {
           "name": "posts",
@@ -88,7 +95,8 @@ func TestSchemaInspect_MarshalJSON(t *testing.T) {
             }
           ]
         }
-      ]
+      ],
+      "comment": "schema comment"
     },
     {
       "name": "temp"
diff --git a/internal/integration/mysql_test.go b/internal/integration/mysql_test.go
index f92afc43..509d4d3d 100644
--- a/internal/integration/mysql_test.go
+++ b/internal/integration/mysql_test.go
@@ -1268,21 +1268,11 @@ create table atlas_types_sanity
 			require.True(t, ok)
 			expected := schema.Table{
 				Name: n,
-				Attrs: func() []schema.Attr {
-					if t.version == "maria107" {
-						return []schema.Attr{
-							&schema.Charset{V: "latin1"},
-							&schema.Collation{V: "latin1_swedish_ci"},
-							&mysql.Engine{V: "InnoDB", Default: true},
-							&schema.Check{Name: "tJSON", Expr: "json_valid(`tJSON`)"},
-						}
-					}
-					return []schema.Attr{
-						&schema.Charset{V: "latin1"},
-						&schema.Collation{V: "latin1_swedish_ci"},
-						&mysql.Engine{V: "InnoDB", Default: true},
-					}
-				}(),
+				Attrs: []schema.Attr{
+					&schema.Charset{V: "latin1"},
+					&schema.Collation{V: "latin1_swedish_ci"},
+					&mysql.Engine{V: "InnoDB", Default: true},
+				},
 				Schema: realm.Schemas[0],
 				Columns: []*schema.Column{
 					func() *schema.Column {
diff --git a/internal/integration/testdata/mysql/column-json.txt b/internal/integration/testdata/mysql/column-json.txt
new file mode 100644
index 00000000..62407968
--- /dev/null
+++ b/internal/integration/testdata/mysql/column-json.txt
@@ -0,0 +1,53 @@
+only maria*
+
+apply 1.hcl
+cmpshow users 1.sql
+
+# The CHECK "json_valid(`name`)" should not be present in the HCL
+# description because the "longtext" is converted to "json" type.
+cmphcl 1.inspect.hcl
+
+-- 1.hcl --
+schema "script_column_json" {}
+
+table "users" {
+  schema = schema.script_column_json
+  column "id" {
+    null = false
+    type = int
+  }
+  column "name" {
+    null = false
+    type = json
+  }
+  primary_key {
+    columns = [column.id]
+  }
+}
+
+-- 1.sql --
+CREATE TABLE `users` (
+  `id` int(11) NOT NULL,
+  `name` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`name`)),
+  PRIMARY KEY (`id`)
+)
+
+-- 1.inspect.hcl --
+table "users" {
+  schema = schema.script_column_json
+  column "id" {
+    null = false
+    type = int
+  }
+  column "name" {
+    null = false
+    type = json
+  }
+  primary_key {
+    columns = [column.id]
+  }
+}
+schema "script_column_json" {
+  charset = "$charset"
+  collate = "$collate"
+}
\ No newline at end of file
diff --git a/sql/mysql/inspect_test.go b/sql/mysql/inspect_test.go
index dc2f6ac1..b2d4126d 100644
--- a/sql/mysql/inspect_test.go
+++ b/sql/mysql/inspect_test.go
@@ -194,7 +194,6 @@ func TestDriver_InspectTable(t *testing.T) {
 					{Name: "jsonc", Type: &schema.ColumnType{Raw: "json", Type: &schema.JSONType{T: "json"}}},
 				}, t.Columns)
 				require.EqualValues([]schema.Attr{
-					&schema.Check{Name: "jsonc", Expr: "json_valid(`jsonc`)"},
 					&schema.Check{Name: "users_chk_1", Expr: `longtext <> '\'\'""'`},
 				}, t.Attrs)
 			},