1 """
2 Dropping resources. For now, you can only drop entire RDs.
3 """
4
5
6
7
8
9
10
11 from gavo import api
12 from gavo import base
13 from gavo import utils
14 from gavo.protocols import tap
15 from gavo.rsc import data
16 from gavo.user import common
17
18
29
30
32 """deletes rows generated from tableName from the DC's metadata
33 (and tableName itself).
34 """
35 q = base.UnmanagedQuerier(conn)
36 for metaTableName, columnName in [
37 ("dc.tablemeta", "tableName"),
38 ("ivoa._obscoresources", "tableName"),
39 ("tap_schema.tables", "table_name"),
40 ("tap_schema.keys", "from_table"),
41 ("tap_schema.keys", "target_table"),
42 ("tap_schema.columns", "table_name")]:
43 if q.getTableType(metaTableName) is not None:
44 q.query("delete from %s where %s=%%(tableName)s"%(
45 metaTableName, columnName),
46 {"tableName": tableName})
47
48 if q.getTableType(tableName) is not None:
49 q.dropTable(tableName, cascade=True)
50
51
53 """tries to "manually" purge a table from the DC's memories.
54
55 This is a "toplevel" function inteded to be called by cli directly.
56 """
57 def parseCmdline():
58 from argparse import ArgumentParser
59 parser = ArgumentParser(
60 description="Removes all traces of the named table within the DC.")
61 parser.add_argument("tablename", help="The name of the table to drop,"
62 " including the schema name.", nargs="+")
63 return parser.parse_args()
64
65 opts = parseCmdline()
66
67 with base.getWritableAdminConn() as conn:
68 for tableName in opts.tablename:
69 _do_dropTable(tableName, conn)
70 conn.execute("DELETE FROM dc.products WHERE sourcetable=%(t)s",
71 {'t': tableName})
72 restoreObscore(conn)
73
74
75 -def _do_dropRD(opts, rdId, connection, selectedIds=()):
76 """drops the data and services defined in the RD selected by rdId.
77 """
78 try:
79 rd = api.getReferencedElement(rdId, forceType=api.RD)
80 except api.NotFoundError:
81 if opts.force:
82 rd = None
83 else:
84 raise
85
86 if rd is not None:
87 if opts.dropAll:
88 dds = rd.dds
89 else:
90 dds = common.getPertainingDDs(rd, selectedIds)
91
92 parseOptions = api.getParseOptions(systemImport=opts.systemImport)
93
94 dgraph = data.DDDependencyGraph(dds, spanRDs=False)
95 dropSequence = dgraph.getDestroySequence()
96 toDrop = set(dds)|set(dropSequence)
97 for dd in dropSequence:
98 api.Data.drop(dd, connection=connection,
99 parseOptions=parseOptions)
100 toDrop.remove(dd)
101 for dd in toDrop:
102 api.Data.drop(dd, connection=connection,
103 parseOptions=parseOptions)
104
105 if not selectedIds or opts.dropAll:
106 from gavo.registry import servicelist
107 servicelist.cleanServiceTablesFor(rd, connection)
108 tap.unpublishFromTAP(rd, connection)
109
110 try:
111 with connection.savepoint():
112 connection.execute("drop schema %s"%rd.schema)
113 except Exception as msg:
114 api.ui.notifyWarning("Cannot drop RD %s's schema %s because:"
115 " %s."%(rd.sourceId, rd.schema, utils.safe_str(msg)))
116
117 else:
118
119
120 for tableName in ["dc.tablemeta", "tap_schema.tables",
121 "tap_schema.columns", "tap_schema.keys", "tap_schema.key_columns",
122 "dc.resources", "dc.interfaces", "dc.sets", "dc.subjects",
123 "dc.authors", "dc.res_dependencies"]:
124 if base.UnmanagedQuerier(connection
125 ).getTableType(tableName) is not None:
126 connection.execute(
127 "delete from %s where sourceRd=%%(sourceRD)s"%tableName,
128 {"sourceRD": rdId})
129
130 restoreObscore(connection)
131
132
134 """parses the command line and drops data and services for the
135 selected RD.
136
137 This is a "toplevel" function inteded to be called by cli directly.
138 """
139 def parseCmdline():
140 from argparse import ArgumentParser
141 parser = ArgumentParser(
142 description="Drops all tables made in an RD's data element.")
143 parser.add_argument("rdid", help="RD path or id to drop")
144 parser.add_argument("ddids", help="Optional dd id(s) if you"
145 " do not want to drop the entire RD. Note that no service"
146 " publications will be undone if you give DD ids.", nargs="*")
147 parser.add_argument("-s", "--system", help="drop tables even if they"
148 " are system tables",
149 dest="systemImport", action="store_true")
150 parser.add_argument("-f", "--force", help="Even if the RD isn't"
151 " found, try to purge entries referencing it. This only"
152 " makes sense with the full RD id.",
153 dest="force", action="store_true")
154 parser.add_argument("--all", help="drop all DDs in the RD,"
155 " not only the auto ones (overrides manual selection)",
156 dest="dropAll", action="store_true")
157 return parser.parse_args()
158
159 opts = parseCmdline()
160 rdId = opts.rdid
161 ddIds = None
162 if opts.ddids:
163 ddIds = set(opts.ddids)
164 with base.getWritableAdminConn() as conn:
165 _do_dropRD(opts, rdId, conn, ddIds)
166