pgxn_utils 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. data/LICENSE +9 -0
  2. data/META.json +32 -10
  3. data/Makefile +1 -1
  4. data/README.md +179 -39
  5. data/Rakefile +77 -14
  6. data/bin/pgxn-bundle +22 -0
  7. data/bin/pgxn-change +22 -0
  8. data/bin/pgxn-release +22 -0
  9. data/bin/pgxn-skeleton +22 -0
  10. data/bin/pgxn-utils +15 -3
  11. data/lib/pgxn_utils/cli.rb +34 -19
  12. data/lib/pgxn_utils/no_tasks.rb +63 -0
  13. data/lib/pgxn_utils/templates/c/%extension_name%.control.tt +5 -0
  14. data/lib/pgxn_utils/templates/c/.gitignore.tt +8 -0
  15. data/lib/pgxn_utils/templates/c/.template +1 -0
  16. data/lib/pgxn_utils/templates/c/META.json.tt +37 -0
  17. data/lib/pgxn_utils/templates/c/Makefile.tt +24 -0
  18. data/lib/pgxn_utils/templates/c/README.md.tt +80 -0
  19. data/lib/pgxn_utils/templates/c/doc/%extension_name%.md.tt +33 -0
  20. data/lib/pgxn_utils/templates/c/sql/%extension_name%.sql.tt +17 -0
  21. data/lib/pgxn_utils/templates/c/sql/uninstall_%extension_name%.sql.tt +1 -0
  22. data/lib/pgxn_utils/templates/c/src/%extension_name%.c.tt +26 -0
  23. data/lib/pgxn_utils/templates/c/test/expected/base.out.tt +9 -0
  24. data/lib/pgxn_utils/templates/c/test/sql/base.sql.tt +10 -0
  25. data/lib/pgxn_utils/templates/fdw/%extension_name%.control.tt +5 -0
  26. data/lib/pgxn_utils/templates/fdw/.gitignore.tt +8 -0
  27. data/lib/pgxn_utils/templates/fdw/.template +1 -0
  28. data/lib/pgxn_utils/templates/fdw/META.json.tt +37 -0
  29. data/lib/pgxn_utils/templates/fdw/Makefile.tt +24 -0
  30. data/lib/pgxn_utils/templates/fdw/README.md.tt +80 -0
  31. data/lib/pgxn_utils/templates/fdw/doc/%extension_name%.md.tt +33 -0
  32. data/lib/pgxn_utils/templates/fdw/sql/%extension_name%.sql.tt +31 -0
  33. data/lib/pgxn_utils/templates/fdw/sql/uninstall_%extension_name%.sql.tt +14 -0
  34. data/lib/pgxn_utils/templates/fdw/src/%extension_name%_fdw.c.tt +323 -0
  35. data/lib/pgxn_utils/templates/fdw/test/expected/base.out.tt +4 -0
  36. data/lib/pgxn_utils/templates/fdw/test/sql/base.sql.tt +8 -0
  37. data/lib/pgxn_utils/templates/root/.gitignore.tt +8 -0
  38. data/lib/pgxn_utils/templates/root/META.json.tt +21 -21
  39. data/lib/pgxn_utils/templates/sql/%extension_name%.control.tt +4 -0
  40. data/lib/pgxn_utils/templates/sql/.gitignore.tt +8 -0
  41. data/lib/pgxn_utils/templates/sql/.template +1 -0
  42. data/lib/pgxn_utils/templates/sql/META.json.tt +27 -0
  43. data/lib/pgxn_utils/templates/sql/Makefile.tt +28 -0
  44. data/lib/pgxn_utils/templates/sql/README.md.tt +80 -0
  45. data/lib/pgxn_utils/templates/sql/doc/%extension_name%.md.tt +33 -0
  46. data/lib/pgxn_utils/templates/sql/sql/%extension_name%.sql.tt +31 -0
  47. data/lib/pgxn_utils/templates/sql/sql/uninstall_%extension_name%.sql.tt +21 -0
  48. data/lib/pgxn_utils/templates/sql/test/expected/base.out.tt +49 -0
  49. data/lib/pgxn_utils/templates/sql/test/sql/base.sql.tt +25 -0
  50. data/lib/pgxn_utils/version.rb +1 -1
  51. data/lib/pgxn_utils.rb +1 -1
  52. data/pgxn_utils.gemspec +21 -30
  53. data/spec/cli_spec.rb +73 -8
  54. data/spec/no_tasks_spec.rb +2 -0
  55. data/spec/spec_helper.rb +21 -4
  56. metadata +87 -30
@@ -0,0 +1,14 @@
1
+ /*
2
+ * Author: <%= maintainer %>
3
+ * Created at: <%= Time.now %>
4
+ *
5
+ */
6
+
7
+ --
8
+ -- This is a example code genereted automaticaly
9
+ -- by pgxn-utils.
10
+
11
+ DROP SERVER <%= extension_name %>_local_service;
12
+ DROP FOREIGN DATA WRAPPER <%= extension_name %>_fdw;
13
+ DROP FUNCTION <%= extension_name %>_fdw_handler();
14
+ DROP FUNCTION <%= extension_name %>_fdw_validator(text[], oid);
@@ -0,0 +1,323 @@
1
+ /*
2
+ * Author: <%= maintainer %>
3
+ * Created at: <%= Time.now %>
4
+ *
5
+ * This is an *example code* genereted automaticaly
6
+ * by pgxn-utils, you must write your own code.
7
+ *
8
+ * Other examples could be found at:
9
+ * http://wiki.postgresql.org/wiki/Foreign_data_wrappers
10
+ *
11
+ */
12
+ #include "postgres.h"
13
+
14
+ /*
15
+ * You can include more files here if needed.
16
+ * To use some types, you must include the
17
+ * correct file here based on:
18
+ * http://www.postgresql.org/docs/current/static/xfunc-c.html#XFUNC-C-TYPE-TABLE
19
+ */
20
+ #include "access/reloptions.h"
21
+ #include "catalog/pg_foreign_table.h"
22
+ #include "catalog/pg_foreign_server.h"
23
+ #include "catalog/pg_user_mapping.h"
24
+ #include "commands/defrem.h"
25
+ #include "commands/explain.h"
26
+ #include "foreign/fdwapi.h"
27
+ #include "foreign/foreign.h"
28
+ #include "funcapi.h"
29
+ #include "miscadmin.h"
30
+ #include "nodes/makefuncs.h"
31
+ #include "optimizer/cost.h"
32
+ #include "utils/rel.h"
33
+ #include "utils/builtins.h"
34
+
35
+ PG_MODULE_MAGIC;
36
+
37
+ /*
38
+ * An example how to handle valid options that
39
+ * could be used by this FDW. You should write
40
+ * your own.
41
+ *
42
+ */
43
+ typedef struct <%= extension_name.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } %>FdwOption
44
+ {
45
+ const char *option_name;
46
+ Oid option_context;
47
+ };
48
+
49
+ /*
50
+ * This is an example how you could enumerate valid options
51
+ * for your FDW. You should write your own.
52
+ */
53
+ static struct <%= extension_name.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } %>FdwOption valid_options[] =
54
+ {
55
+ {"server_address", ForeignServerRelationId },
56
+ {"server_port", ForeignServerRelationId },
57
+
58
+ {"user", UserMappingRelationId },
59
+ {"password", UserMappingRelationId },
60
+
61
+ {"table", ForeignTableRelationId},
62
+
63
+ {NULL, InvalidOid}
64
+ };
65
+
66
+ /*
67
+ * Handler and Validator functions
68
+ */
69
+ extern Datum <%= extension_name %>_fdw_handler(PG_FUNCTION_ARGS);
70
+ extern Datum <%= extension_name %>_fdw_validator(PG_FUNCTION_ARGS);
71
+
72
+ PG_FUNCTION_INFO_V1(<%= extension_name %>_fdw_handler);
73
+ PG_FUNCTION_INFO_V1(<%= extension_name %>_fdw_validator);
74
+
75
+ /*
76
+ * FDW functions declarations
77
+ */
78
+ static FdwPlan *<%= extension_name %>_plan(Oid foreign_table_id, PlannerInfo *root, RelOptInfo *base_relation);
79
+ static void <%= extension_name %>_explain(ForeignScanState *node, ExplainState *es);
80
+ static void <%= extension_name %>_begin(ForeignScanState *node, int eflags);
81
+ static TupleTableSlot *<%= extension_name %>_iterate(ForeignScanState *node);
82
+ static void <%= extension_name %>_rescan(ForeignScanState *node);
83
+ static void <%= extension_name %>_end(ForeignScanState *node);
84
+
85
+ /*
86
+ * Helper functions
87
+ */
88
+ static bool is_valid_option(const char *option, Oid context);
89
+ static void <%= extension_name %>_get_options(Oid foreign_table_id, char **server_address, int *server_port, char **user, char **password, char **table)
90
+
91
+ /*
92
+ * FDW functions implementation
93
+ */
94
+
95
+ Datum
96
+ <%= extension_name %>_fdw_handler(PG_FUNCTION_ARGS)
97
+ {
98
+ FdwRoutine *fdw_routine = makeNode(FdwRoutine);
99
+
100
+ fdw_routine->PlanForeignScan = <%= extension_name %>_plan;
101
+ fdw_routine->ExplainForeignScan = <%= extension_name %>_explain;
102
+ fdw_routine->BeginForeignScan = <%= extension_name %>_begin;
103
+ fdw_routine->IterateForeignScan = <%= extension_name %>_iterate;
104
+ fdw_routine->ReScanForeignScan = <%= extension_name %>_rescan;
105
+ fdw_routine->EndForeignScan = <%= extension_name %>_end;
106
+
107
+ PG_RETURN_POINTER(fdw_routine);
108
+ }
109
+
110
+ Datum
111
+ <%= extension_name %>_fdw_validator(PG_FUNCTION_ARGS)
112
+ {
113
+ /*
114
+ * This is an example how you could validate the
115
+ * your FDW options. You should write your own
116
+ * validator.
117
+ */
118
+
119
+ List *options_list = untransformRelOptions(PG_GETARG_DATUM(0));
120
+ Oid catalog = PG_GETARG_OID(1);
121
+ ListCell *cell;
122
+
123
+ foreach(cell, options_list)
124
+ {
125
+ DefElem *def = (DefElem *) lfirst(cell);
126
+
127
+ if (!is_valid_option(def->defname, catalog))
128
+ {
129
+ struct <%= extension_name.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } %>FdwOption *opt;
130
+ StringInfoData buf;
131
+
132
+ /*
133
+ * Unknown option specified, complain about it. Provide a hint
134
+ * with list of valid options for the object.
135
+ */
136
+ initStringInfo(&buf);
137
+ for (opt = valid_options; opt->option_name; opt++)
138
+ {
139
+ if (catalog == opt->option_context)
140
+ appendStringInfo(&buf, "%s%s", (buf.len > 0) ? ", " : "",
141
+ opt->option_name);
142
+ }
143
+
144
+ ereport(ERROR,
145
+ (errcode(ERRCODE_FDW_INVALID_OPTION_NAME),
146
+ errmsg("invalid option \"%s\"", def->defname),
147
+ errhint("Valid options in this context are: %s",
148
+ buf.data)));
149
+ }
150
+ }
151
+
152
+ PG_RETURN_BOOL(true);
153
+ }
154
+
155
+ static FdwPlan *
156
+ <%= extension_name %>_plan( Oid foreign_table_id,
157
+ PlannerInfo *root,
158
+ RelOptInfo *base_relation)
159
+ {
160
+ /*
161
+ * Plan a scan on a foreign table. This is called when a query is planned.
162
+ * foreign_table_id is the pg_class OID of the foreign table. root is the
163
+ * planner's global information about the query, and base_relation is the
164
+ * planner's information about this table. This is an example and you
165
+ * should write your own.
166
+ *
167
+ * see: http://www.postgresql.org/docs/current/static/fdw-callbacks.html
168
+ */
169
+
170
+ FdwPlan *fdw_plan;
171
+
172
+ fdw_plan = makeNode(FdwPlan);
173
+
174
+ fdw_plan->startup_cost = /* calculate and return a startup cost */;
175
+ base_relation->rows = /* calculate and return an extimation of row many rows this call will return */;
176
+ fdw_plan->total_cost = /* calculate and return an total cost extimation */;
177
+
178
+ return fdw_plan;
179
+ }
180
+
181
+ static void
182
+ <%= extension_name %>_explain(ForeignScanState *node, ExplainState *es)
183
+ {
184
+ /*
185
+ * Print additional EXPLAIN output for a foreign table scan. This can just
186
+ * return if there is no need to print anything. Otherwise, it should call
187
+ * ExplainPropertyText and related functions to add fields to the EXPLAIN
188
+ * output. This is an example and you should write your own.
189
+ *
190
+ * see: http://www.postgresql.org/docs/current/static/fdw-callbacks.html
191
+ */
192
+
193
+ /* calculate real values for costs */
194
+ ExplainPropertyText("Foreign <%= extension_name.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } %>", "<%= extension_name %>", es);
195
+
196
+ if (es->costs)
197
+ {
198
+ ExplainPropertyLong("Foreign <%= extension_name.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } %> cost", /* calculated costs */, es);
199
+ }
200
+ }
201
+
202
+ static void
203
+ <%= extension_name %>_begin(ForeignScanState *node, int eflags)
204
+ {
205
+ /*
206
+ * Begin executing a foreign scan. This is called during executor startup.
207
+ * It should perform any initialization needed before the scan can start,
208
+ * but not start executing the actual scan (that should be done upon the
209
+ * first call to IterateForeignScan)
210
+ *
211
+ * see: http://www.postgresql.org/docs/current/static/fdw-callbacks.html
212
+ */
213
+ }
214
+
215
+ static TupleTableSlot *
216
+ <%= extension_name %>_iterate(ForeignScanState *node)
217
+ {
218
+ /*
219
+ * Fetch one row from the foreign source, returning it in a tuple table slot
220
+ * (the node's ScanTupleSlot should be used for this purpose). Return NULL
221
+ * if no more rows are available.
222
+ *
223
+ * see: http://www.postgresql.org/docs/current/static/fdw-callbacks.html
224
+ */
225
+
226
+ }
227
+
228
+ static void
229
+ <%= extension_name %>_rescan(ForeignScanState *node)
230
+ {
231
+ /*
232
+ * Restart the scan from the beginning.
233
+ *
234
+ * see: http://www.postgresql.org/docs/current/static/fdw-callbacks.html
235
+ */
236
+ }
237
+
238
+ static void
239
+ <%= extension_name %>_end(ForeignScanState *node)
240
+ {
241
+ /*
242
+ * End the scan and release resources. It is normally not important to
243
+ * release palloc'd memory, but for example open files and connections
244
+ * to remote servers should be cleaned up.
245
+ *
246
+ * see: http://www.postgresql.org/docs/current/static/fdw-callbacks.html
247
+ */
248
+ }
249
+
250
+ /*
251
+ * Helper functions
252
+ */
253
+
254
+ /*
255
+ * Example function to check if the provided option is one of the
256
+ * valid options where context is the Oid of the catalog holding
257
+ * the object the option is for.
258
+ */
259
+ static bool
260
+ is_valid_option(const char *option, Oid context)
261
+ {
262
+ struct <%= extension_name.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } %>FdwOption *opt;
263
+
264
+ for (opt = valid_options; opt->option_name; opt++)
265
+ {
266
+ if (context == opt->option_context && strcmp(opt->option_name, option) == 0)
267
+ return true;
268
+ }
269
+ return false;
270
+ }
271
+
272
+ /*
273
+ * Fetch the options for a <%= extension_name %>_fdw foreign table.
274
+ * This is an example and you should write your own.
275
+ */
276
+ static void
277
+ <%= extension_name %>_get_options(Oid foreign_table_id, char **server_address, int *server_port, char **user, char **password, char **table)
278
+ {
279
+ ForeignTable *f_table;
280
+ ForeignServer *f_server;
281
+ UserMapping *f_mapping;
282
+ List *options;
283
+ ListCell *lc;
284
+
285
+ /*
286
+ * Extract options from FDW objects.
287
+ */
288
+ f_table = GetForeignTable(foreign_table_id);
289
+ f_server = GetForeignServer(f_table->serverid);
290
+ f_mapping = GetUserMapping(GetUserId(), f_table->serverid);
291
+
292
+ options = NIL;
293
+ options = list_concat(options, f_table->options);
294
+ options = list_concat(options, f_server->options);
295
+ options = list_concat(options, f_mapping->options);
296
+
297
+ foreach(lc, options)
298
+ {
299
+ DefElem *def = (DefElem *) lfirst(lc);
300
+
301
+ if (strcmp(def->defname, "server_address") == 0)
302
+ *server_address = defGetString(def);
303
+
304
+ if (strcmp(def->defname, "server_port") == 0)
305
+ *server_port = atoi(defGetString(def));
306
+
307
+ if (strcmp(def->defname, "user") == 0)
308
+ *user = defGetString(def);
309
+
310
+ if (strcmp(def->defname, "password") == 0)
311
+ *password = defGetString(def);
312
+
313
+ if (strcmp(def->defname, "table") == 0)
314
+ *table = defGetString(def);
315
+ }
316
+
317
+ /* Default values, if required */
318
+ if (!*server_address)
319
+ *server_address = "127.0.0.1";
320
+
321
+ if (!*server_port)
322
+ *port = 12345;
323
+ }
@@ -0,0 +1,4 @@
1
+ \set ECHO 0
2
+ -- You should write your tests
3
+
4
+ ROLLBACK;
@@ -0,0 +1,8 @@
1
+ \set ECHO 0
2
+ BEGIN;
3
+ \i sql/<%= extension_name %>.sql
4
+ \set ECHO all
5
+
6
+ -- You should write your tests
7
+
8
+ ROLLBACK;
@@ -0,0 +1,8 @@
1
+ results/
2
+ *.so
3
+ tmp/
4
+ *.o
5
+ regression.diffs
6
+ regression.out
7
+ /sql/<%= extension_name =>--*
8
+ !/sql/<%= extension_name =>--*--*.sql
@@ -1,27 +1,27 @@
1
1
  {
2
- "name": "<%= extension_name %>",
3
- "abstract": "<%= abstract %>",
4
- "description": "<%= description %>",
5
- "version": "<%= version %>",
6
- "maintainer": "<%= maintainer %>",
7
- "license": "<%= license %>",
8
- "provides": {
9
- "<%= extension_name %>": {
10
- "abstract": "<%= abstract %>",
11
- "file": "sql/<%= extension_name %>.sql",
12
- "docfile": "doc/<%= extension_name %>.md",
13
- "version": "<%= version %>"
14
- }
15
- },
16
- "release_status": "<%= release_status %>",
2
+ "name": "<%= extension_name %>",
3
+ "abstract": "<%= abstract %>",
4
+ "description": "<%= description %>",
5
+ "version": "<%= version %>",
6
+ "maintainer": "<%= maintainer %>",
7
+ "license": "<%= license %>",
8
+ "provides": {
9
+ "<%= extension_name %>": {
10
+ "abstract": "<%= abstract %>",
11
+ "file": "sql/<%= extension_name %>.sql",
12
+ "docfile": "doc/<%= extension_name %>.md",
13
+ "version": "<%= version %>"
14
+ }
15
+ },
16
+ "release_status": "<%= release_status %>",
17
17
  <% if generated_by %>
18
- "generated_by": "<%= generated_by %>",
18
+ "generated_by": "<%= generated_by %>",
19
19
  <% end %>
20
20
  <% if tags %>
21
- "tags": [ <%= tags.collect { |t| %Q|"#{t}"| }.join(",") %> ],
21
+ "tags": [ <%= tags.collect { |t| %Q|"#{t}"| }.join(",") %> ],
22
22
  <% end %>
23
- "meta-spec": {
24
- "version": "1.0.0",
25
- "url": "http://pgxn.org/meta/spec.txt"
26
- }
23
+ "meta-spec": {
24
+ "version": "1.0.0",
25
+ "url": "http://pgxn.org/meta/spec.txt"
26
+ }
27
27
  }
@@ -0,0 +1,4 @@
1
+ # <%= extension_name %> extension
2
+ comment = '<%= abstract %>'
3
+ default_version = '<%= version %>'
4
+ relocatable = true
@@ -0,0 +1,8 @@
1
+ results/
2
+ *.so
3
+ tmp/
4
+ *.o
5
+ regression.diffs
6
+ regression.out
7
+ /sql/<%= extension_name =>--*
8
+ !/sql/<%= extension_name =>--*--*.sql
@@ -0,0 +1 @@
1
+ sql
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "<%= extension_name %>",
3
+ "abstract": "<%= abstract %>",
4
+ "description": "<%= description %>",
5
+ "version": "<%= version %>",
6
+ "maintainer": "<%= maintainer %>",
7
+ "license": "<%= license %>",
8
+ "provides": {
9
+ "<%= extension_name %>": {
10
+ "abstract": "<%= abstract %>",
11
+ "file": "sql/<%= extension_name %>.sql",
12
+ "docfile": "doc/<%= extension_name %>.md",
13
+ "version": "<%= version %>"
14
+ }
15
+ },
16
+ "release_status": "<%= release_status %>",
17
+ <% if generated_by %>
18
+ "generated_by": "<%= generated_by %>",
19
+ <% end %>
20
+ <% if tags %>
21
+ "tags": [ <%= tags.collect { |t| %Q|"#{t}"| }.join(",") %> ],
22
+ <% end %>
23
+ "meta-spec": {
24
+ "version": "1.0.0",
25
+ "url": "http://pgxn.org/meta/spec.txt"
26
+ }
27
+ }
@@ -0,0 +1,28 @@
1
+ EXTENSION = <%= extension_name %>
2
+ EXTVERSION = $(shell grep default_version $(EXTENSION).control | sed -e "s/default_version[[:space:]]*=[[:space:]]*'\([^']*\)'/\1/")
3
+
4
+ DATA = $(filter-out $(wildcard sql/*--*.sql),$(wildcard sql/*.sql))
5
+ DOCS = $(wildcard doc/*.md)
6
+ TESTS = $(wildcard test/sql/*.sql)
7
+ REGRESS = $(patsubst test/sql/%.sql,%,$(TESTS))
8
+ REGRESS_OPTS = --inputdir=test --load-language=plpgsql
9
+ #
10
+ # Uncoment the MODULES line if you are adding C files
11
+ # to your extention.
12
+ #
13
+ #MODULES = $(patsubst %.c,%,$(wildcard src/*.c))
14
+ PG_CONFIG = pg_config
15
+ PG91 = $(shell $(PG_CONFIG) --version | grep -qE " 8\.| 9\.0" && echo no || echo yes)
16
+
17
+ ifeq ($(PG91),yes)
18
+ all: sql/$(EXTENSION)--$(EXTVERSION).sql
19
+
20
+ sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql
21
+ cp $< $@
22
+
23
+ DATA = $(wildcard sql/*--*.sql) sql/$(EXTENSION)--$(EXTVERSION).sql
24
+ EXTRA_CLEAN = sql/$(EXTENSION)--$(EXTVERSION).sql
25
+ endif
26
+
27
+ PGXS := $(shell $(PG_CONFIG) --pgxs)
28
+ include $(PGXS)
@@ -0,0 +1,80 @@
1
+ <%= extension_name %>
2
+ <%= extension_name.gsub(/./,"=") %>
3
+
4
+ <%= description %>
5
+
6
+ To build it, just do this:
7
+
8
+ make
9
+ make installcheck
10
+ make install
11
+
12
+ If you encounter an error such as:
13
+
14
+ "Makefile", line 8: Need an operator
15
+
16
+ You need to use GNU make, which may well be installed on your system as
17
+ `gmake`:
18
+
19
+ gmake
20
+ gmake install
21
+ gmake installcheck
22
+
23
+ If you encounter an error such as:
24
+
25
+ make: pg_config: Command not found
26
+
27
+ Be sure that you have `pg_config` installed and in your path. If you used a
28
+ package management system such as RPM to install PostgreSQL, be sure that the
29
+ `-devel` package is also installed. If necessary tell the build process where
30
+ to find it:
31
+
32
+ env PG_CONFIG=/path/to/pg_config make && make installcheck && make install
33
+
34
+ And finally, if all that fails (and if you're on PostgreSQL 8.1 or lower, it
35
+ likely will), copy the entire distribution directory to the `contrib/`
36
+ subdirectory of the PostgreSQL source tree and try it there without
37
+ `pg_config`:
38
+
39
+ env NO_PGXS=1 make && make installcheck && make install
40
+
41
+ If you encounter an error such as:
42
+
43
+ ERROR: must be owner of database regression
44
+
45
+ You need to run the test suite using a super user, such as the default
46
+ "postgres" super user:
47
+
48
+ make installcheck PGUSER=postgres
49
+
50
+ Once <%= extension_name %> is installed, you can add it to a database. If you're running
51
+ PostgreSQL 9.1.0 or greater, it's a simple as connecting to a database as a
52
+ super user and running:
53
+
54
+ CREATE EXTENSION <%= extension_name %>;
55
+
56
+ If you've upgraded your cluster to PostgreSQL 9.1 and already had <%= extension_name %>
57
+ installed, you can upgrade it to a properly packaged extension with:
58
+
59
+ CREATE EXTENSION <%= extension_name %> FROM unpackaged;
60
+
61
+ For versions of PostgreSQL less than 9.1.0, you'll need to run the
62
+ installation script:
63
+
64
+ psql -d mydb -f /path/to/pgsql/share/contrib/<%= extension_name %>.sql
65
+
66
+ If you want to install <%= extension_name %> and all of its supporting objects into a specific
67
+ schema, use the `PGOPTIONS` environment variable to specify the schema, like
68
+ so:
69
+
70
+ PGOPTIONS=--search_path=extensions psql -d mydb -f <%= extension_name %>.sql
71
+
72
+ Dependencies
73
+ ------------
74
+ The `<%= extension_name %>` data type has no dependencies other than PostgreSQL.
75
+
76
+ Copyright and License
77
+ ---------------------
78
+
79
+ Copyright (c) <%= Time.now.strftime("%Y") %> <%= maintainer %>.
80
+
@@ -0,0 +1,33 @@
1
+ <%= extension_name %>
2
+ <%= extension_name.gsub(/./,"=") %>
3
+
4
+ Synopsis
5
+ --------
6
+
7
+ Show a brief synopsis of the extension.
8
+
9
+ Description
10
+ -----------
11
+
12
+ <%= description %>
13
+
14
+ Usage
15
+ -----
16
+
17
+ Show usage.
18
+
19
+ Support
20
+ -------
21
+
22
+ There is issues tracker? Github? Put this information here.
23
+
24
+ Author
25
+ ------
26
+
27
+ [<%= maintainer %>]
28
+
29
+ Copyright and License
30
+ ---------------------
31
+
32
+ Copyright (c) <%= Time.now.strftime("%Y") %> <%= maintainer %>.
33
+
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Author: <%= maintainer %>
3
+ * Created at: <%= Time.now %>
4
+ *
5
+ */
6
+
7
+ --
8
+ -- This is a example code genereted automaticaly
9
+ -- by pgxn-utils.
10
+
11
+ SET client_min_messages = warning;
12
+
13
+ -- If your extension will create a type you can
14
+ -- do somenthing like this
15
+ CREATE TYPE <%= extension_name %> AS ( a text, b text );
16
+
17
+ -- Maybe you want to create some function, so you can use
18
+ -- this as an example
19
+ CREATE OR REPLACE FUNCTION <%= extension_name %> (text, text)
20
+ RETURNS <%= extension_name %> LANGUAGE SQL AS 'SELECT ROW($1, $2)::<%= extension_name %>';
21
+
22
+ -- Sometimes it is common to use special operators to
23
+ -- work with your new created type, you can create
24
+ -- one like the command bellow if it is applicable
25
+ -- to your case
26
+
27
+ CREATE OPERATOR #? (
28
+ LEFTARG = text,
29
+ RIGHTARG = text,
30
+ PROCEDURE = <%= extension_name %>
31
+ );
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Author: <%= maintainer %>
3
+ * Created at: <%= Time.now %>
4
+ *
5
+ */
6
+
7
+ --
8
+ -- This is a example code genereted automaticaly
9
+ -- by pgxn-utils.
10
+
11
+ SET client_min_messages = warning;
12
+
13
+ BEGIN;
14
+
15
+ -- You can use this statements as
16
+ -- template for your extension.
17
+
18
+ DROP OPERATOR #? (text, text);
19
+ DROP FUNCTION <%= extension_name %>(text, text);
20
+ DROP TYPE <%= extension_name %> CASCADE;
21
+ COMMIT;