2016-10-04 12:05:51 +02:00
package postgresql
import (
2016-12-12 22:15:57 +01:00
"bytes"
2016-11-02 15:36:39 +01:00
"database/sql"
2016-12-12 22:15:57 +01:00
"errors"
2016-10-04 12:05:51 +02:00
"fmt"
2016-12-12 10:33:02 +01:00
"log"
2016-10-04 12:05:51 +02:00
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/helper/schema"
"github.com/lib/pq"
)
2016-12-12 22:15:57 +01:00
const (
2016-12-12 23:37:40 +01:00
extNameAttr = "name"
extSchemaAttr = "schema"
extVersionAttr = "version"
2016-12-12 22:15:57 +01:00
)
2016-10-04 12:05:51 +02:00
func resourcePostgreSQLExtension ( ) * schema . Resource {
return & schema . Resource {
Create : resourcePostgreSQLExtensionCreate ,
2016-11-02 15:36:39 +01:00
Read : resourcePostgreSQLExtensionRead ,
2016-12-12 22:15:57 +01:00
Update : resourcePostgreSQLExtensionUpdate ,
2016-10-04 12:05:51 +02:00
Delete : resourcePostgreSQLExtensionDelete ,
2016-12-12 10:33:02 +01:00
Importer : & schema . ResourceImporter {
State : schema . ImportStatePassthrough ,
} ,
2016-10-04 12:05:51 +02:00
Schema : map [ string ] * schema . Schema {
2016-12-12 22:15:57 +01:00
extNameAttr : {
2016-10-04 12:05:51 +02:00
Type : schema . TypeString ,
Required : true ,
ForceNew : true ,
} ,
2016-12-12 22:15:57 +01:00
extSchemaAttr : {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
Description : "Sets the schema of an extension" ,
} ,
2016-12-12 23:37:40 +01:00
extVersionAttr : {
Type : schema . TypeString ,
Optional : true ,
Computed : true ,
Description : "Sets the version number of the extension" ,
} ,
2016-10-04 12:05:51 +02:00
} ,
}
}
func resourcePostgreSQLExtensionCreate ( d * schema . ResourceData , meta interface { } ) error {
2016-12-12 10:33:02 +01:00
c := meta . ( * Client )
conn , err := c . Connect ( )
2016-10-04 12:05:51 +02:00
if err != nil {
return err
}
defer conn . Close ( )
2016-12-12 22:15:57 +01:00
extName := d . Get ( extNameAttr ) . ( string )
b := bytes . NewBufferString ( "CREATE EXTENSION " )
fmt . Fprintf ( b , pq . QuoteIdentifier ( extName ) )
2016-10-04 12:05:51 +02:00
2016-12-12 22:15:57 +01:00
if v , ok := d . GetOk ( extSchemaAttr ) ; ok {
fmt . Fprint ( b , " SCHEMA " , pq . QuoteIdentifier ( v . ( string ) ) )
}
2016-12-12 23:37:40 +01:00
if v , ok := d . GetOk ( extVersionAttr ) ; ok {
fmt . Fprint ( b , " VERSION " , pq . QuoteIdentifier ( v . ( string ) ) )
}
2016-12-12 22:15:57 +01:00
query := b . String ( )
2016-10-04 12:05:51 +02:00
_ , err = conn . Query ( query )
if err != nil {
return errwrap . Wrapf ( "Error creating extension: {{err}}" , err )
}
2016-12-12 22:15:57 +01:00
d . SetId ( extName )
2016-10-04 12:05:51 +02:00
2016-11-02 15:36:39 +01:00
return resourcePostgreSQLExtensionRead ( d , meta )
}
func resourcePostgreSQLExtensionRead ( d * schema . ResourceData , meta interface { } ) error {
2016-12-12 10:33:02 +01:00
c := meta . ( * Client )
conn , err := c . Connect ( )
2016-11-02 15:36:39 +01:00
if err != nil {
return err
}
defer conn . Close ( )
2016-12-12 22:40:49 +01:00
extID := d . Id ( )
2016-12-12 23:37:40 +01:00
var extName , extSchema , extVersion string
err = conn . QueryRow ( "SELECT e.extname, n.nspname, e.extversion FROM pg_catalog.pg_extension e, pg_catalog.pg_namespace n WHERE n.oid = e.extnamespace AND e.extname = $1" , extID ) . Scan ( & extName , & extSchema , & extVersion )
2016-11-02 15:36:39 +01:00
switch {
case err == sql . ErrNoRows :
2016-12-12 10:33:02 +01:00
log . Printf ( "[WARN] PostgreSQL extension (%s) not found" , d . Id ( ) )
2016-11-02 15:36:39 +01:00
d . SetId ( "" )
return nil
case err != nil :
return errwrap . Wrapf ( "Error reading extension: {{err}}" , err )
default :
2016-12-12 22:15:57 +01:00
d . Set ( extNameAttr , extName )
d . Set ( extSchemaAttr , extSchema )
2016-12-12 23:37:40 +01:00
d . Set ( extVersionAttr , extVersion )
2016-12-12 22:15:57 +01:00
d . SetId ( extName )
2016-11-02 15:36:39 +01:00
return nil
}
2016-10-04 12:05:51 +02:00
}
func resourcePostgreSQLExtensionDelete ( d * schema . ResourceData , meta interface { } ) error {
2016-12-12 10:33:02 +01:00
c := meta . ( * Client )
conn , err := c . Connect ( )
2016-10-04 12:05:51 +02:00
if err != nil {
return err
}
defer conn . Close ( )
2016-12-12 22:40:49 +01:00
extID := d . Id ( )
2016-10-04 12:05:51 +02:00
2016-12-12 22:40:49 +01:00
query := fmt . Sprintf ( "DROP EXTENSION %s" , pq . QuoteIdentifier ( extID ) )
2016-10-04 12:05:51 +02:00
_ , err = conn . Query ( query )
if err != nil {
return errwrap . Wrapf ( "Error deleting extension: {{err}}" , err )
}
d . SetId ( "" )
return nil
}
2016-12-12 22:15:57 +01:00
func resourcePostgreSQLExtensionUpdate ( d * schema . ResourceData , meta interface { } ) error {
c := meta . ( * Client )
conn , err := c . Connect ( )
if err != nil {
return err
}
defer conn . Close ( )
// Can't rename a schema
if err := setExtSchema ( conn , d ) ; err != nil {
return err
}
2016-12-12 23:37:40 +01:00
if err := setExtVersion ( conn , d ) ; err != nil {
return err
}
2016-12-12 22:15:57 +01:00
return resourcePostgreSQLExtensionRead ( d , meta )
}
func setExtSchema ( conn * sql . DB , d * schema . ResourceData ) error {
if ! d . HasChange ( extSchemaAttr ) {
return nil
}
2016-12-12 22:40:49 +01:00
extID := d . Id ( )
_ , nraw := d . GetChange ( extSchemaAttr )
2016-12-12 22:15:57 +01:00
n := nraw . ( string )
if n == "" {
return errors . New ( "Error setting extension name to an empty string" )
}
2016-12-12 22:40:49 +01:00
query := fmt . Sprintf ( "ALTER EXTENSION %s SET SCHEMA %s" , pq . QuoteIdentifier ( extID ) , pq . QuoteIdentifier ( n ) )
2016-12-12 22:15:57 +01:00
if _ , err := conn . Query ( query ) ; err != nil {
return errwrap . Wrapf ( "Error updating extension SCHEMA: {{err}}" , err )
}
return nil
}
2016-12-12 23:37:40 +01:00
func setExtVersion ( conn * sql . DB , d * schema . ResourceData ) error {
if ! d . HasChange ( extVersionAttr ) {
return nil
}
extID := d . Id ( )
b := bytes . NewBufferString ( "ALTER EXTENSION " )
fmt . Fprintf ( b , "%s UPDATE" , pq . QuoteIdentifier ( extID ) )
_ , nraw := d . GetChange ( extVersionAttr )
n := nraw . ( string )
if n != "" {
fmt . Fprintf ( b , " TO %s" , pq . QuoteIdentifier ( n ) )
}
query := b . String ( )
if _ , err := conn . Query ( query ) ; err != nil {
return errwrap . Wrapf ( "Error updating extension version: {{err}}" , err )
}
return nil
}