github.com/ffrizzo/terraform@v0.8.2-0.20161219200057-992e12335f3d/builtin/providers/postgresql/resource_postgresql_extension.go (about)

     1  package postgresql
     2  
     3  import (
     4  	"bytes"
     5  	"database/sql"
     6  	"errors"
     7  	"fmt"
     8  	"log"
     9  
    10  	"github.com/hashicorp/errwrap"
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  	"github.com/lib/pq"
    13  )
    14  
    15  const (
    16  	extNameAttr    = "name"
    17  	extSchemaAttr  = "schema"
    18  	extVersionAttr = "version"
    19  )
    20  
    21  func resourcePostgreSQLExtension() *schema.Resource {
    22  	return &schema.Resource{
    23  		Create: resourcePostgreSQLExtensionCreate,
    24  		Read:   resourcePostgreSQLExtensionRead,
    25  		Update: resourcePostgreSQLExtensionUpdate,
    26  		Delete: resourcePostgreSQLExtensionDelete,
    27  		Importer: &schema.ResourceImporter{
    28  			State: schema.ImportStatePassthrough,
    29  		},
    30  
    31  		Schema: map[string]*schema.Schema{
    32  			extNameAttr: {
    33  				Type:     schema.TypeString,
    34  				Required: true,
    35  				ForceNew: true,
    36  			},
    37  			extSchemaAttr: {
    38  				Type:        schema.TypeString,
    39  				Optional:    true,
    40  				Computed:    true,
    41  				Description: "Sets the schema of an extension",
    42  			},
    43  			extVersionAttr: {
    44  				Type:        schema.TypeString,
    45  				Optional:    true,
    46  				Computed:    true,
    47  				Description: "Sets the version number of the extension",
    48  			},
    49  		},
    50  	}
    51  }
    52  
    53  func resourcePostgreSQLExtensionCreate(d *schema.ResourceData, meta interface{}) error {
    54  	c := meta.(*Client)
    55  	conn, err := c.Connect()
    56  	if err != nil {
    57  		return err
    58  	}
    59  	defer conn.Close()
    60  
    61  	extName := d.Get(extNameAttr).(string)
    62  
    63  	b := bytes.NewBufferString("CREATE EXTENSION ")
    64  	fmt.Fprintf(b, pq.QuoteIdentifier(extName))
    65  
    66  	if v, ok := d.GetOk(extSchemaAttr); ok {
    67  		fmt.Fprint(b, " SCHEMA ", pq.QuoteIdentifier(v.(string)))
    68  	}
    69  
    70  	if v, ok := d.GetOk(extVersionAttr); ok {
    71  		fmt.Fprint(b, " VERSION ", pq.QuoteIdentifier(v.(string)))
    72  	}
    73  
    74  	query := b.String()
    75  	_, err = conn.Query(query)
    76  	if err != nil {
    77  		return errwrap.Wrapf("Error creating extension: {{err}}", err)
    78  	}
    79  
    80  	d.SetId(extName)
    81  
    82  	return resourcePostgreSQLExtensionRead(d, meta)
    83  }
    84  
    85  func resourcePostgreSQLExtensionRead(d *schema.ResourceData, meta interface{}) error {
    86  	c := meta.(*Client)
    87  	conn, err := c.Connect()
    88  	if err != nil {
    89  		return err
    90  	}
    91  	defer conn.Close()
    92  
    93  	extID := d.Id()
    94  	var extName, extSchema, extVersion string
    95  	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)
    96  	switch {
    97  	case err == sql.ErrNoRows:
    98  		log.Printf("[WARN] PostgreSQL extension (%s) not found", d.Id())
    99  		d.SetId("")
   100  		return nil
   101  	case err != nil:
   102  		return errwrap.Wrapf("Error reading extension: {{err}}", err)
   103  	default:
   104  		d.Set(extNameAttr, extName)
   105  		d.Set(extSchemaAttr, extSchema)
   106  		d.Set(extVersionAttr, extVersion)
   107  		d.SetId(extName)
   108  		return nil
   109  	}
   110  }
   111  
   112  func resourcePostgreSQLExtensionDelete(d *schema.ResourceData, meta interface{}) error {
   113  	c := meta.(*Client)
   114  	conn, err := c.Connect()
   115  	if err != nil {
   116  		return err
   117  	}
   118  	defer conn.Close()
   119  
   120  	extID := d.Id()
   121  
   122  	query := fmt.Sprintf("DROP EXTENSION %s", pq.QuoteIdentifier(extID))
   123  	_, err = conn.Query(query)
   124  	if err != nil {
   125  		return errwrap.Wrapf("Error deleting extension: {{err}}", err)
   126  	}
   127  
   128  	d.SetId("")
   129  
   130  	return nil
   131  }
   132  
   133  func resourcePostgreSQLExtensionUpdate(d *schema.ResourceData, meta interface{}) error {
   134  	c := meta.(*Client)
   135  	conn, err := c.Connect()
   136  	if err != nil {
   137  		return err
   138  	}
   139  	defer conn.Close()
   140  
   141  	// Can't rename a schema
   142  
   143  	if err := setExtSchema(conn, d); err != nil {
   144  		return err
   145  	}
   146  
   147  	if err := setExtVersion(conn, d); err != nil {
   148  		return err
   149  	}
   150  
   151  	return resourcePostgreSQLExtensionRead(d, meta)
   152  }
   153  
   154  func setExtSchema(conn *sql.DB, d *schema.ResourceData) error {
   155  	if !d.HasChange(extSchemaAttr) {
   156  		return nil
   157  	}
   158  
   159  	extID := d.Id()
   160  	_, nraw := d.GetChange(extSchemaAttr)
   161  	n := nraw.(string)
   162  	if n == "" {
   163  		return errors.New("Error setting extension name to an empty string")
   164  	}
   165  
   166  	query := fmt.Sprintf("ALTER EXTENSION %s SET SCHEMA %s", pq.QuoteIdentifier(extID), pq.QuoteIdentifier(n))
   167  	if _, err := conn.Query(query); err != nil {
   168  		return errwrap.Wrapf("Error updating extension SCHEMA: {{err}}", err)
   169  	}
   170  
   171  	return nil
   172  }
   173  
   174  func setExtVersion(conn *sql.DB, d *schema.ResourceData) error {
   175  	if !d.HasChange(extVersionAttr) {
   176  		return nil
   177  	}
   178  
   179  	extID := d.Id()
   180  
   181  	b := bytes.NewBufferString("ALTER EXTENSION ")
   182  	fmt.Fprintf(b, "%s UPDATE", pq.QuoteIdentifier(extID))
   183  
   184  	_, nraw := d.GetChange(extVersionAttr)
   185  	n := nraw.(string)
   186  	if n != "" {
   187  		fmt.Fprintf(b, " TO %s", pq.QuoteIdentifier(n))
   188  	}
   189  
   190  	query := b.String()
   191  	if _, err := conn.Query(query); err != nil {
   192  		return errwrap.Wrapf("Error updating extension version: {{err}}", err)
   193  	}
   194  
   195  	return nil
   196  }