2016-12-12 16:35:41 +01:00
package postgresql
import (
"bytes"
"database/sql"
"errors"
"fmt"
"log"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/helper/schema"
"github.com/lib/pq"
)
const (
2016-12-14 10:04:35 +01:00
schemaNameAttr = "name"
schemaOwnerAttr = "owner"
2016-12-12 16:35:41 +01:00
)
func resourcePostgreSQLSchema ( ) * schema . Resource {
return & schema . Resource {
Create : resourcePostgreSQLSchemaCreate ,
Read : resourcePostgreSQLSchemaRead ,
Update : resourcePostgreSQLSchemaUpdate ,
Delete : resourcePostgreSQLSchemaDelete ,
Importer : & schema . ResourceImporter {
State : schema . ImportStatePassthrough ,
} ,
Schema : map [ string ] * schema . Schema {
schemaNameAttr : {
Type : schema . TypeString ,
Required : true ,
Description : "The name of the schema" ,
} ,
2016-12-14 10:04:35 +01:00
schemaOwnerAttr : {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
Description : "The ROLE name who owns the schema" ,
} ,
2016-12-12 16:35:41 +01:00
} ,
}
}
func resourcePostgreSQLSchemaCreate ( d * schema . ResourceData , meta interface { } ) error {
c := meta . ( * Client )
conn , err := c . Connect ( )
if err != nil {
return errwrap . Wrapf ( "Error connecting to PostgreSQL: {{err}}" , err )
}
defer conn . Close ( )
schemaName := d . Get ( schemaNameAttr ) . ( string )
b := bytes . NewBufferString ( "CREATE SCHEMA " )
fmt . Fprintf ( b , pq . QuoteIdentifier ( schemaName ) )
2016-12-14 10:04:35 +01:00
switch v , ok := d . GetOk ( schemaOwnerAttr ) ; {
case ok :
fmt . Fprint ( b , " AUTHORIZATION " , pq . QuoteIdentifier ( v . ( string ) ) )
}
2016-12-12 16:35:41 +01:00
query := b . String ( )
_ , err = conn . Query ( query )
if err != nil {
return errwrap . Wrapf ( fmt . Sprintf ( "Error creating schema %s: {{err}}" , schemaName ) , err )
}
d . SetId ( schemaName )
return resourcePostgreSQLSchemaRead ( d , meta )
}
func resourcePostgreSQLSchemaDelete ( d * schema . ResourceData , meta interface { } ) error {
client := meta . ( * Client )
conn , err := client . Connect ( )
if err != nil {
return err
}
defer conn . Close ( )
schemaName := d . Get ( schemaNameAttr ) . ( string )
query := fmt . Sprintf ( "DROP SCHEMA %s" , pq . QuoteIdentifier ( schemaName ) )
_ , err = conn . Query ( query )
if err != nil {
return errwrap . Wrapf ( "Error deleting schema: {{err}}" , err )
}
d . SetId ( "" )
return nil
}
func resourcePostgreSQLSchemaRead ( d * schema . ResourceData , meta interface { } ) error {
c := meta . ( * Client )
conn , err := c . Connect ( )
if err != nil {
return err
}
defer conn . Close ( )
schemaId := d . Id ( )
2016-12-14 10:04:35 +01:00
var schemaName , schemaOwner string
err = conn . QueryRow ( "SELECT nspname, pg_catalog.pg_get_userbyid(nspowner) FROM pg_catalog.pg_namespace WHERE nspname=$1" , schemaId ) . Scan ( & schemaName , & schemaOwner )
2016-12-12 16:35:41 +01:00
switch {
case err == sql . ErrNoRows :
log . Printf ( "[WARN] PostgreSQL schema (%s) not found" , schemaId )
d . SetId ( "" )
return nil
case err != nil :
return errwrap . Wrapf ( "Error reading schema: {{err}}" , err )
default :
d . Set ( schemaNameAttr , schemaName )
2016-12-14 10:04:35 +01:00
d . Set ( schemaOwnerAttr , schemaOwner )
2016-12-12 16:35:41 +01:00
d . SetId ( schemaName )
return nil
}
}
func resourcePostgreSQLSchemaUpdate ( d * schema . ResourceData , meta interface { } ) error {
c := meta . ( * Client )
conn , err := c . Connect ( )
if err != nil {
return err
}
defer conn . Close ( )
if err := setSchemaName ( conn , d ) ; err != nil {
return err
}
2016-12-14 10:04:35 +01:00
if err := setSchemaOwner ( conn , d ) ; err != nil {
return err
}
2016-12-12 16:35:41 +01:00
return resourcePostgreSQLSchemaRead ( d , meta )
}
func setSchemaName ( conn * sql . DB , d * schema . ResourceData ) error {
if ! d . HasChange ( schemaNameAttr ) {
return nil
}
oraw , nraw := d . GetChange ( schemaNameAttr )
o := oraw . ( string )
n := nraw . ( string )
if n == "" {
return errors . New ( "Error setting schema name to an empty string" )
}
query := fmt . Sprintf ( "ALTER SCHEMA %s RENAME TO %s" , pq . QuoteIdentifier ( o ) , pq . QuoteIdentifier ( n ) )
if _ , err := conn . Query ( query ) ; err != nil {
return errwrap . Wrapf ( "Error updating schema NAME: {{err}}" , err )
}
d . SetId ( n )
return nil
}
2016-12-14 10:04:35 +01:00
func setSchemaOwner ( conn * sql . DB , d * schema . ResourceData ) error {
if ! d . HasChange ( schemaOwnerAttr ) {
return nil
}
oraw , nraw := d . GetChange ( schemaOwnerAttr )
o := oraw . ( string )
n := nraw . ( string )
if n == "" {
return errors . New ( "Error setting schema owner to an empty string" )
}
query := fmt . Sprintf ( "ALTER SCHEMA %s OWNER TO %s" , pq . QuoteIdentifier ( o ) , pq . QuoteIdentifier ( n ) )
if _ , err := conn . Query ( query ) ; err != nil {
return errwrap . Wrapf ( "Error updating schema OWNER: {{err}}" , err )
}
return nil
}