[CalendarServer-changes] [15654] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri Jun 3 12:49:02 PDT 2016
Revision: 15654
http://trac.calendarserver.org//changeset/15654
Author: cdaboo at apple.com
Date: 2016-06-03 12:49:01 -0700 (Fri, 03 Jun 2016)
Log Message:
-----------
psql-based schema check now does all the same checks that the internal txn based schema check does.
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/tools/checkdatabaseschema.py
CalendarServer/trunk/requirements-cs.txt
Modified: CalendarServer/trunk/calendarserver/tools/checkdatabaseschema.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/checkdatabaseschema.py 2016-06-03 19:47:17 UTC (rev 15653)
+++ CalendarServer/trunk/calendarserver/tools/checkdatabaseschema.py 2016-06-03 19:49:01 UTC (rev 15654)
@@ -16,13 +16,20 @@
from __future__ import print_function
from getopt import getopt, GetoptError
+
+from twext.enterprise.dal.model import Schema, Table, Column, Sequence, SQLType, \
+ Constraint, Function
+from twext.enterprise.dal.parseschema import addSQLToSchema, schemaFromPath
+
+from twisted.python.filepath import FilePath
+
+from txdav.common.datastore.sql_dump import DTYPE_MAP_POSTGRES, \
+ DEFAULTVALUE_MAP_POSTGRES
+
import os
import re
import subprocess
import sys
-from twext.enterprise.dal.model import Schema, Table, Column, Sequence
-from twext.enterprise.dal.parseschema import addSQLToSchema, schemaFromPath
-from twisted.python.filepath import FilePath
USERNAME = "caldav"
DATABASENAME = "caldav"
@@ -86,7 +93,7 @@
(PSQL, e.output, e.returncode)
)
- return [s.strip() for s in out.splitlines()[:-1]]
+ return [map(lambda x: x.strip(), s.split("|")) for s in out.splitlines()[:-1]]
@@ -103,7 +110,7 @@
)
try:
- version = int(out[0])
+ version = int(out[0][0])
except ValueError, e:
raise CheckSchemaError(
"Failed to parse schema version: %s" % (e,)
@@ -114,51 +121,109 @@
def dumpCurrentSchema(verbose=False):
+ schemaname = "public"
+
schema = Schema("Dumped schema")
- tables = {}
+ # Sequences
+ seqs = {}
+ rows = execSQL(
+ "Schema sequences...",
+ "select sequence_name from information_schema.sequences where sequence_schema = '%s';" % (schemaname,),
+ verbose
+ )
+ for row in rows:
+ name = row[0]
+ seqs[name.upper()] = Sequence(schema, name.upper())
+
# Tables
+ tables = {}
rows = execSQL(
"Schema tables...",
- "select table_name from information_schema.tables where table_schema = 'public';",
+ "select table_name from information_schema.tables where table_schema = '%s';" % (schemaname,),
verbose
)
for row in rows:
- name = row
- table = Table(schema, name)
- tables[name] = table
+ name = row[0]
+ table = Table(schema, name.upper())
+ tables[name.upper()] = table
# Columns
rows = execSQL(
"Reading table '{}' columns...".format(name),
- "select column_name from information_schema.columns where table_schema = 'public' and table_name = '{}';".format(name),
- verbose
+ "select column_name, data_type, is_nullable, character_maximum_length, column_default from information_schema.columns where table_schema = '%s' and table_name = '%s';" % (schemaname, name,),
+ verbose,
)
- for row in rows:
- name = row
+ for name, datatype, is_nullable, charlen, default in rows:
# TODO: figure out the type
- column = Column(table, name, None)
+ column = Column(table, name.upper(), SQLType(DTYPE_MAP_POSTGRES.get(datatype, datatype), int(charlen) if charlen else 0))
table.columns.append(column)
+ if default:
+ if default.startswith("nextval("):
+ dname = default.split("'")[1].split(".")[-1]
+ column.default = seqs[dname.upper()]
+ elif default in DEFAULTVALUE_MAP_POSTGRES:
+ column.default = DEFAULTVALUE_MAP_POSTGRES[default]
+ else:
+ try:
+ column.default = int(default)
+ except ValueError:
+ column.default = default
+ if is_nullable == "NO":
+ table.tableConstraint(Constraint.NOT_NULL, [column.name, ])
+ # Key columns
+ keys = {}
+ rows = execSQL(
+ "Schema key columns...",
+ "select constraint_name, table_name, column_name from information_schema.key_column_usage where constraint_schema = '%s';" % (schemaname,),
+ verbose
+ )
+ for conname, tname, cname in rows:
+ keys[conname] = (tname, cname)
+
+ # Constraints
+ constraints = {}
+ rows = execSQL(
+ "SChema constraints...",
+ "select constraint_name, table_name, column_name from information_schema.constraint_column_usage where constraint_schema = '%s';" % (schemaname,),
+ verbose
+ )
+ for conname, tname, cname in rows:
+ constraints[conname] = (tname, cname)
+
+ # References - referential_constraints
+ rows = execSQL(
+ "Schema referential constraints...",
+ "select constraint_name, unique_constraint_name, delete_rule from information_schema.referential_constraints where constraint_schema = '%s';" % (schemaname,),
+ verbose
+ )
+ for conname, uconname, delete in rows:
+ table = tables[keys[conname][0].upper()]
+ column = table.columnNamed(keys[conname][1].upper())
+ column.doesReferenceName(constraints[uconname][0].upper())
+ if delete != "NO ACTION":
+ column.deleteAction = delete.lower()
+
# Indexes
# TODO: handle implicit indexes created via primary key() and unique() statements within CREATE TABLE
rows = execSQL(
"Schema indexes...",
- "select indexdef from pg_indexes where schemaname = 'public';",
+ "select indexdef from pg_indexes where schemaname = '%s';" % (schemaname,),
verbose
)
for indexdef in rows:
- addSQLToSchema(schema, indexdef.replace("public.", ""))
+ addSQLToSchema(schema, indexdef[0].replace("%s." % (schemaname,), "").upper())
- # Sequences
+ # Functions
rows = execSQL(
- "Schema sequences...",
- "select sequence_name from information_schema.sequences where sequence_schema = 'public';",
+ "Schema functions",
+ "select routine_name from information_schema.routines where routine_schema = '%s';" % (schemaname,),
verbose
)
for row in rows:
- name = row
- Sequence(schema, name)
+ name = row[0]
+ Function(schema, name)
return schema
@@ -227,7 +292,7 @@
if skt.basename().startswith("ccs_postgres_"):
PGSOCKETDIR = skt.path
PSQL = "/Applications/Server.app/Contents/ServerRoot/usr/bin/psql"
- SCHEMADIR = "/Applications/Server.app/Contents/ServerRoot/usr/share/caldavd/lib/python/txdav/common/datastore/sql_schema/"
+ SCHEMADIR = "/Applications/Server.app/Contents/ServerRoot/Library/CalendarServer/lib/python2.7/site-packages/txdav/common/datastore/sql_schema/"
elif opt in ("-v", "--verbose"):
verbose = True
else:
Modified: CalendarServer/trunk/requirements-cs.txt
===================================================================
--- CalendarServer/trunk/requirements-cs.txt 2016-06-03 19:47:17 UTC (rev 15653)
+++ CalendarServer/trunk/requirements-cs.txt 2016-06-03 19:49:01 UTC (rev 15654)
@@ -7,7 +7,7 @@
zope.interface==4.1.3
setuptools==18.5
- --editable svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@15633#egg=twextpy
+ --editable svn+http://svn.calendarserver.org/repository/calendarserver/twext/trunk@15653#egg=twextpy
cffi==1.3.0
pycparser==2.14
#twisted
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20160603/66f03d9a/attachment-0001.html>
More information about the calendarserver-changes
mailing list