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 }