ProcruSQL 0.0.16__tar.gz → 0.0.18__tar.gz

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.
@@ -1,10 +1,11 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: ProcruSQL
3
- Version: 0.0.16
3
+ Version: 0.0.18
4
4
  Summary: Make a database fit its description
5
5
  Home-page: https://git.hjp.at:3000/hjp/procrusql
6
6
  Author: Peter J. Holzer
7
7
  Author-email: hjp@hjp.at
8
+ License: MIT
8
9
  Project-URL: Bug Tracker, https://git.hjp.at:3000/hjp/procrusql/issues
9
10
  Project-URL: Repository, https://git.hjp.at:3000/hjp/procrusql
10
11
  Classifier: Programming Language :: Python :: 3
@@ -13,6 +14,7 @@ Classifier: Operating System :: OS Independent
13
14
  Requires-Python: >=3.8
14
15
  Description-Content-Type: text/markdown
15
16
  License-File: LICENSE
17
+ Dynamic: license-file
16
18
 
17
19
  ProcruSQL
18
20
  =========
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = ProcruSQL
3
- version = 0.0.16
3
+ version = 0.0.18
4
4
  author = Peter J. Holzer
5
5
  author_email = hjp@hjp.at
6
6
  description = Make a database fit its description
@@ -14,6 +14,8 @@ classifiers =
14
14
  Programming Language :: Python :: 3
15
15
  License :: OSI Approved :: MIT License
16
16
  Operating System :: OS Independent
17
+ license = MIT
18
+ license_files = LICENSE
17
19
 
18
20
  [options]
19
21
  package_dir =
@@ -1,10 +1,11 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: ProcruSQL
3
- Version: 0.0.16
3
+ Version: 0.0.18
4
4
  Summary: Make a database fit its description
5
5
  Home-page: https://git.hjp.at:3000/hjp/procrusql
6
6
  Author: Peter J. Holzer
7
7
  Author-email: hjp@hjp.at
8
+ License: MIT
8
9
  Project-URL: Bug Tracker, https://git.hjp.at:3000/hjp/procrusql/issues
9
10
  Project-URL: Repository, https://git.hjp.at:3000/hjp/procrusql
10
11
  Classifier: Programming Language :: Python :: 3
@@ -13,6 +14,7 @@ Classifier: Operating System :: OS Independent
13
14
  Requires-Python: >=3.8
14
15
  Description-Content-Type: text/markdown
15
16
  License-File: LICENSE
17
+ Dynamic: license-file
16
18
 
17
19
  ProcruSQL
18
20
  =========
@@ -296,6 +296,33 @@ class HaveIndex(Node):
296
296
  self.ok = True
297
297
  log_state.info("%s is now ok", self.name)
298
298
 
299
+ class HaveExtension(Node):
300
+ def __init__(self, name, depends, extension):
301
+ super().__init__(name, depends)
302
+ self.extension = extension
303
+
304
+ def check(self):
305
+ log_check.info("Checking %s", self.name)
306
+ csr = db.cursor(cursor_factory=extras.DictCursor)
307
+ csr.execute("select * from pg_extension where extname = %s", (self.extension,))
308
+ r = csr.fetchall()
309
+ if len(r) == 1:
310
+ # extension exists, all ok
311
+ self.set_order()
312
+ self.ok = True
313
+ log_state.info("%s is now ok", self.name)
314
+ return
315
+ if len(r) > 1:
316
+ raise RuntimeError(f"Found {len(r)} extensions with name {self.extension}")
317
+
318
+ # Create it
319
+ log_action.info(f"Creating extension {self.extension}")
320
+ q = sql.SQL("create extension {extension}".format(extension=self.extension))
321
+ csr.execute(q)
322
+ self.set_order()
323
+ self.ok = True
324
+ log_state.info("%s is now ok", self.name)
325
+
299
326
 
300
327
  def findnode(name):
301
328
  for w in want:
@@ -80,7 +80,8 @@ def parse_ruleset(ps):
80
80
  parse_column_rule(ps2) or \
81
81
  parse_data_rule(ps2) or \
82
82
  parse_index_rule(ps2) or \
83
- parse_view_rule(ps2)
83
+ parse_view_rule(ps2) or \
84
+ parse_extension_rule(ps2)
84
85
  if ps3:
85
86
  ps2.ast.append(ps3.ast)
86
87
  ps2.position = ps3.position
@@ -288,6 +289,22 @@ def parse_view_rule(ps):
288
289
  ps2.skip_whitespace_and_comments()
289
290
  ps3 = parse_multiline_string(ps2)
290
291
 
292
+ def parse_extension_rule(ps):
293
+ ps2 = ps.clone()
294
+ ps2.skip_whitespace_and_comments()
295
+ if not ps2.match(r"extension\b"):
296
+ ps.record_child_failure(ps2, "expected “extension”")
297
+ return
298
+ ps2.skip_whitespace_and_comments()
299
+ ps3 = parse_extension_name(ps2)
300
+ if not ps3:
301
+ ps.record_child_failure(ps2, "expected extension name")
302
+ return
303
+ ps2.skip_whitespace_and_comments()
304
+
305
+ ps2.ast = procrusql.HaveExtension(rulename(), [], ps3.ast[0])
306
+ ps2.position = ps3.position
307
+ return ps2
291
308
 
292
309
 
293
310
  def parse_table_name(ps):
@@ -339,6 +356,21 @@ def parse_index_name(ps):
339
356
  ps.record_child_failure(ps2, "expected index name")
340
357
  return
341
358
 
359
+ def parse_extension_name(ps):
360
+ # this is an exact duplicate of parse_table_name and parse_column_name, but they will
361
+ # probably diverge, so I duplicated it. I probably should define a
362
+ # parse_identifier and redefine them in terms of it.
363
+ ps2 = ps.clone()
364
+ ps2.ast = []
365
+ ps2.skip_whitespace_and_comments()
366
+ if ps2.rest[0].isalpha():
367
+ m = ps2.match(r"\w+") # always succeeds since we already checked the first character
368
+ ps2.ast.append(m.group(0))
369
+ return ps2
370
+ else:
371
+ ps.record_child_failure(ps2, "expected extension name")
372
+ return
373
+
342
374
  def parse_column_definition(ps):
343
375
  ps2 = ps.clone()
344
376
  ps2.ast = []
@@ -348,6 +380,7 @@ def parse_column_definition(ps):
348
380
  "integer", "int", "serial", "bigint",
349
381
  "boolean",
350
382
  "text", "character varying",
383
+ "citext",
351
384
  "date", "timestamp with time zone", "timestamptz",
352
385
  "time",
353
386
  "inet",
@@ -355,11 +388,17 @@ def parse_column_definition(ps):
355
388
  "json", "jsonb",
356
389
  "uuid",
357
390
  r"integer\[\]", r"int\[\]", r"bigint\[\]",
391
+ r"text\[\]",
392
+ r"citext\[\]",
358
393
  "bytea",
359
394
  ),
360
395
  key=lambda x: -len(x) # longest match first
361
396
  )
362
- pattern = "(" + "|".join(sqltypes) + ")" + r"([ \t]+(default .*|not null\b|primary key\b|unique\b|references \w+\b))*"
397
+ pattern = "(" + "|".join(sqltypes) + ")" + r"([ \t]+(default .*|not null\b|primary key\b|unique\b|references \w+\b( on delete cascade)?))*"
398
+ # XXX - I think we should separate constraints from columns
399
+ # Either completely (separate declarations in the source), or by producing
400
+ # two rules (HaveColumn, HaveForeignKey) from one declaration (if that is
401
+ # possible).
363
402
  m = ps2.match(pattern)
364
403
  if not m:
365
404
  ps.record_child_failure(ps2, "expected column definition")
File without changes
File without changes
File without changes