Skip to content

Commit

Permalink
Schema resource & data sources (#83)
Browse files Browse the repository at this point in the history
* Schema resource

* Resource import test fix

* Schema data source

* Schemas list data source

* Resource import test fix

* Resource import test fix

* Docs and validation fixes
  • Loading branch information
tkielar-pgs authored Oct 24, 2022
1 parent a88219e commit 1495c24
Show file tree
Hide file tree
Showing 26 changed files with 1,115 additions and 9 deletions.
39 changes: 39 additions & 0 deletions docs/data-sources/schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "mssql_schema Data Source - terraform-provider-mssql"
subcategory: ""
description: |-
Retrieves information about DB schema.
---

# mssql_schema (Data Source)

Retrieves information about DB schema.

## Example Usage

```terraform
data "mssql_database" "example" {
name = "example"
}
data "mssql_schema" "by_name" {
database_id = data.mssql_database.example.id
name = "dbo"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Optional

- `database_id` (String) ID of database. Can be retrieved using `mssql_database` or `SELECT DB_ID('<db_name>')`.
- `id` (String) `<database_id>/<schema_id>`. Schema ID can be retrieved using `SELECT SCHEMA_ID('<schema_name>')`. Either `id` or `name` must be provided.
- `name` (String) Schema name. Either `id` or `name` must be provided.

### Read-Only

- `owner_id` (String) ID of database role or user owning this schema. Can be retrieved using `mssql_database_role`, `mssql_sql_user`, `mssql_azuread_user` or `mssql_azuread_service_principal`


51 changes: 51 additions & 0 deletions docs/data-sources/schemas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "mssql_schemas Data Source - terraform-provider-mssql"
subcategory: ""
description: |-
Obtains information about all schemas found in SQL database.
---

# mssql_schemas (Data Source)

Obtains information about all schemas found in SQL database.

## Example Usage

```terraform
data "mssql_database" "example" {
name = "example"
}
data "mssql_schemas" "all" {
database_id = data.mssql_database.example.id
}
output "all_schema_names" {
value = data.mssql_schemas.all.schemas[*].name
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Optional

- `database_id` (String) ID of database. Can be retrieved using `mssql_database` or `SELECT DB_ID('<db_name>')`. Defaults to ID of `master`.

### Read-Only

- `id` (String) ID of the data source, equals to database ID
- `schemas` (Attributes Set) Set of schemas found in the DB. (see [below for nested schema](#nestedatt--schemas))

<a id="nestedatt--schemas"></a>
### Nested Schema for `schemas`

Read-Only:

- `database_id` (String) ID of database. Can be retrieved using `mssql_database` or `SELECT DB_ID('<db_name>')`.
- `id` (String) `<database_id>/<schema_id>`. Schema ID can be retrieved using `SELECT SCHEMA_ID('<schema_name>')`.
- `name` (String) Schema name.
- `owner_id` (String) ID of database role or user owning this schema. Can be retrieved using `mssql_database_role`, `mssql_sql_user`, `mssql_azuread_user` or `mssql_azuread_service_principal`


54 changes: 54 additions & 0 deletions docs/resources/schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "mssql_schema Resource - terraform-provider-mssql"
subcategory: ""
description: |-
Manages single DB schema.
---

# mssql_schema (Resource)

Manages single DB schema.

## Example Usage

```terraform
data "mssql_database" "example" {
name = "example"
}
data "mssql_sql_user" "owner" {
name = "example_user"
}
resource "mssql_schema" "example" {
name = "example"
database_id = data.mssql_database.example.id
owner_id = data.mssql_sql_user.owner.id
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `name` (String) Schema name.

### Optional

- `database_id` (String) ID of database. Can be retrieved using `mssql_database` or `SELECT DB_ID('<db_name>')`. Defaults to ID of `master`.
- `owner_id` (String) ID of database role or user owning this schema. Can be retrieved using `mssql_database_role`, `mssql_sql_user`, `mssql_azuread_user` or `mssql_azuread_service_principal`

### Read-Only

- `id` (String) `<database_id>/<schema_id>`. Schema ID can be retrieved using `SELECT SCHEMA_ID('<schema_name>')`.

## Import

Import is supported using the following syntax:

```shell
# import using <db_id>/<schema_id> - can be retrieved using `SELECT CONCAT(DB_ID(), '/', SCHEMA_ID('<schema_name>'))`
terraform import mssql_schema.example '7/5'
```
8 changes: 8 additions & 0 deletions examples/data-sources/mssql_schema/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
data "mssql_database" "example" {
name = "example"
}

data "mssql_schema" "by_name" {
database_id = data.mssql_database.example.id
name = "dbo"
}
11 changes: 11 additions & 0 deletions examples/data-sources/mssql_schemas/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
data "mssql_database" "example" {
name = "example"
}

data "mssql_schemas" "all" {
database_id = data.mssql_database.example.id
}

output "all_schema_names" {
value = data.mssql_schemas.all.schemas[*].name
}
2 changes: 2 additions & 0 deletions examples/resources/mssql_schema/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# import using <db_id>/<schema_id> - can be retrieved using `SELECT CONCAT(DB_ID(), '/', SCHEMA_ID('<schema_name>'))`
terraform import mssql_schema.example '7/5'
13 changes: 13 additions & 0 deletions examples/resources/mssql_schema/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
data "mssql_database" "example" {
name = "example"
}

data "mssql_sql_user" "owner" {
name = "example_user"
}

resource "mssql_schema" "example" {
name = "example"
database_id = data.mssql_database.example.id
owner_id = data.mssql_sql_user.owner.id
}
14 changes: 14 additions & 0 deletions internal/acctest/testContext.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/stretchr/testify/require"
"net/url"
"os"
"strings"
"testing"
"time"
)
Expand Down Expand Up @@ -190,6 +191,19 @@ func (t *TestContext) Test(testCase resource.TestCase) {
resource.Test(t.t, testCase)
}

func (t *TestContext) FormatId(idParts ...any) string {
str := make([]string, len(idParts))
for i, id := range idParts {
str[i] = fmt.Sprint(id)
}

return strings.Join(str, "/")
}

func (t *TestContext) DefaultDbId(idParts ...any) string {
return t.FormatId(append([]any{t.DefaultDBId}, idParts...)...)
}

func (t *TestContext) setSqlConnectionDetails() {
t.sqlDriverName = "sqlserver"
t.sqlConnString = url.URL{
Expand Down
27 changes: 21 additions & 6 deletions internal/core/datasource/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,22 @@ type ConfigureRequest struct {
Conn sql.Connection
}

var _ utils.ErrorMonad = ReadRequest[any]{}
var _ utils.ErrorMonad = MonadRequest{}

type ReadRequest[TData any] struct {
monad utils.ErrorMonad
Conn sql.Connection
Config TData
type MonadRequest struct {
monad utils.ErrorMonad
}

func (r ReadRequest[TData]) Then(f func()) utils.ErrorMonad {
func (r MonadRequest) Then(f func()) utils.ErrorMonad {
return r.monad.Then(f)
}

type ReadRequest[TData any] struct {
MonadRequest
Conn sql.Connection
Config TData
}

type ReadResponse[TData any] struct {
state TData
exists bool
Expand All @@ -40,3 +44,14 @@ type DataSource[TData any] interface {
GetSchema(ctx context.Context) tfsdk.Schema
Read(ctx context.Context, req ReadRequest[TData], resp *ReadResponse[TData])
}

type ValidateRequest[TData any] struct {
MonadRequest
Config TData
}

type ValidateResponse[TData any] struct{}

type DataSourceWithValidation[TData any] interface {
Validate(ctx context.Context, req ValidateRequest[TData], resp *ValidateResponse[TData])
}
18 changes: 18 additions & 0 deletions internal/core/datasource/datasourceWrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
)

var _ datasource.DataSourceWithValidateConfig = &dataSourceWrapper[any]{}

func NewDataSource[T any](d DataSource[T]) func() datasource.DataSourceWithConfigure {
return func() datasource.DataSourceWithConfigure {
return &dataSourceWrapper[T]{d: d}
Expand Down Expand Up @@ -66,3 +68,19 @@ func (d *dataSourceWrapper[T]) Read(ctx context.Context, req datasource.ReadRequ
}
})
}

func (d *dataSourceWrapper[T]) ValidateConfig(ctx context.Context, req datasource.ValidateConfigRequest, resp *datasource.ValidateConfigResponse) {
dsWithValidation, ok := d.d.(DataSourceWithValidation[T])
if !ok {
return
}

ctx = utils.WithDiagnostics(ctx, &resp.Diagnostics)

request := ValidateRequest[T]{}
request.monad = utils.StopOnError(ctx).
Then(func() { request.Config = utils.GetData[T](ctx, req.Config) })

response := ValidateResponse[T]{}
dsWithValidation.Validate(ctx, request, &response)
}
2 changes: 2 additions & 0 deletions internal/provider/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/PGSSoft/terraform-provider-mssql/internal/services/database"
"github.com/PGSSoft/terraform-provider-mssql/internal/services/databaseRole"
"github.com/PGSSoft/terraform-provider-mssql/internal/services/databaseRoleMember"
"github.com/PGSSoft/terraform-provider-mssql/internal/services/schema"
"github.com/PGSSoft/terraform-provider-mssql/internal/services/script"
"github.com/PGSSoft/terraform-provider-mssql/internal/services/sqlLogin"
"github.com/PGSSoft/terraform-provider-mssql/internal/services/sqlUser"
Expand All @@ -22,6 +23,7 @@ func Services() []core.Service {
databaseRoleMember.Service(),
sqlLogin.Service(),
sqlUser.Service(),
schema.Service(),

script.Service(),
}
Expand Down
46 changes: 46 additions & 0 deletions internal/services/schema/base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package schema

import (
"context"
"fmt"
"github.com/PGSSoft/terraform-provider-mssql/internal/services/common"
"github.com/PGSSoft/terraform-provider-mssql/internal/sql"
"github.com/PGSSoft/terraform-provider-mssql/internal/validators"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var attributes = map[string]tfsdk.Attribute{
"id": {
MarkdownDescription: "`<database_id>/<schema_id>`. Schema ID can be retrieved using `SELECT SCHEMA_ID('<schema_name>')`.",
Type: types.StringType,
},
"database_id": common.DatabaseIdAttribute,
"name": {
MarkdownDescription: "Schema name.",
Type: types.StringType,
Validators: validators.SchemaNameValidators,
},
"owner_id": {
MarkdownDescription: "ID of database role or user owning this schema. Can be retrieved using `mssql_database_role`, `mssql_sql_user`, `mssql_azuread_user` or `mssql_azuread_service_principal`",
Type: types.StringType,
},
}

type resourceData struct {
Id types.String `tfsdk:"id"`
DatabaseId types.String `tfsdk:"database_id"`
Name types.String `tfsdk:"name"`
OwnerId types.String `tfsdk:"owner_id"`
}

func (d resourceData) withSchemaData(ctx context.Context, schema sql.Schema) resourceData {
dbId := schema.GetDb(ctx).GetId(ctx)

return resourceData{
Id: types.String{Value: common.DbObjectId[sql.SchemaId]{DbId: dbId, ObjectId: schema.GetId(ctx)}.String()},
Name: types.String{Value: schema.GetName(ctx)},
DatabaseId: types.String{Value: fmt.Sprint(dbId)},
OwnerId: types.String{Value: common.DbObjectId[sql.GenericDatabasePrincipalId]{DbId: dbId, ObjectId: schema.GetOwnerId(ctx)}.String()},
}
}
Loading

0 comments on commit 1495c24

Please sign in to comment.