al-data-utils 0.3.1__py3-none-any.whl
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.
- al_data_utils/__init__.py +10 -0
- al_data_utils/airflow_utils/__init__.py +13 -0
- al_data_utils/airflow_utils/airflow_utils.py +83 -0
- al_data_utils/azure_as_utils/__init__.py +31 -0
- al_data_utils/azure_as_utils/auth.py +82 -0
- al_data_utils/azure_as_utils/azure_as_utils.py +223 -0
- al_data_utils/azure_as_utils/client.py +158 -0
- al_data_utils/azure_as_utils/errors.py +78 -0
- al_data_utils/azure_as_utils/models.py +265 -0
- al_data_utils/azure_as_utils/poller.py +121 -0
- al_data_utils/backup_utils/__init__.py +9 -0
- al_data_utils/backup_utils/mssql/dacpac/__init__.py +1 -0
- al_data_utils/backup_utils/mssql/dacpac/sqlpackage.py +207 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/__init__.py +8 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/config.py +150 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/emit/__init__.py +11 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/emit/foreign_keys.py +38 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/emit/indexes.py +37 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/emit/sql_objects.py +17 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/emit/tables.py +139 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/introspect/__init__.py +19 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/introspect/foreign_keys.py +173 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/introspect/functions.py +133 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/introspect/indexes.py +190 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/introspect/sequences.py +180 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/introspect/stored_procedures.py +313 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/introspect/synonyms.py +135 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/introspect/tables.py +251 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/introspect/views.py +244 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/io/__init__.py +10 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/io/layout.py +28 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/io/writer.py +40 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/models/__init__.py +14 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/models/foreign_key_def.py +19 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/models/index_def.py +19 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/models/sql_object_def.py +11 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/models/table_column_def.py +27 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/models/table_def.py +22 -0
- al_data_utils/backup_utils/mssql/schema_snapshot/snapshot_processor.py +754 -0
- al_data_utils/backup_utils/mssql/scripter/__init__.py +1 -0
- al_data_utils/config_utils/__init__.py +6 -0
- al_data_utils/config_utils/config_utils.py +31 -0
- al_data_utils/files_sync_utils/__init__.py +15 -0
- al_data_utils/files_sync_utils/files_sync_utils.py +567 -0
- al_data_utils/geo_utils/__init__.py +0 -0
- al_data_utils/git_utils/__init__.py +27 -0
- al_data_utils/git_utils/git_utils.py +142 -0
- al_data_utils/logging_utils/__init__.py +3 -0
- al_data_utils/logging_utils/logging_utils.py +39 -0
- al_data_utils/ones_api_utils/__init__.py +3 -0
- al_data_utils/ones_api_utils/ones_api_utils.py +61 -0
- al_data_utils/sql_utils/__init__.py +3 -0
- al_data_utils/sql_utils/sql_utils.py +158 -0
- al_data_utils/tg_utils/__init__.py +3 -0
- al_data_utils/tg_utils/tg_utils.py +45 -0
- al_data_utils-0.3.1.dist-info/METADATA +157 -0
- al_data_utils-0.3.1.dist-info/RECORD +60 -0
- al_data_utils-0.3.1.dist-info/WHEEL +5 -0
- al_data_utils-0.3.1.dist-info/licenses/LICENSE +21 -0
- al_data_utils-0.3.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from al_data_utils.sql_utils.sql_utils import UnifiedSQLClient
|
|
4
|
+
from ..models import SqlObjectDef
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
_SQL_FUNCTIONS = r"""
|
|
8
|
+
select
|
|
9
|
+
s.name as schema_name,
|
|
10
|
+
o.name as object_name,
|
|
11
|
+
convert(nvarchar(max), m.definition) as definition
|
|
12
|
+
from sys.objects o
|
|
13
|
+
inner join sys.schemas s
|
|
14
|
+
on s.schema_id = o.schema_id
|
|
15
|
+
inner join sys.sql_modules m
|
|
16
|
+
on m.object_id = o.object_id
|
|
17
|
+
where o.is_ms_shipped = 0
|
|
18
|
+
and o.type in ('FN', 'IF', 'TF', 'FS', 'FT')
|
|
19
|
+
order by s.name, o.name;
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _normalized_set(values: set[str] | None) -> set[str]:
|
|
24
|
+
if not values:
|
|
25
|
+
return set()
|
|
26
|
+
return {str(v).strip().lower() for v in values if str(v).strip()}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _split_qualified(values: set[str]) -> list[tuple[str, str]]:
|
|
30
|
+
pairs: list[tuple[str, str]] = []
|
|
31
|
+
for v in sorted(values):
|
|
32
|
+
if '.' not in v:
|
|
33
|
+
continue
|
|
34
|
+
schema, name = v.split('.', 1)
|
|
35
|
+
schema = schema.strip().lower()
|
|
36
|
+
name = name.strip().lower()
|
|
37
|
+
if schema and name:
|
|
38
|
+
pairs.append((schema, name))
|
|
39
|
+
return pairs
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _build_filter_sql_and_params(
|
|
43
|
+
*,
|
|
44
|
+
include_schemas: set[str] | None = None,
|
|
45
|
+
exclude_schemas: set[str] | None = None,
|
|
46
|
+
include_objects: set[str] | None = None,
|
|
47
|
+
exclude_objects: set[str] | None = None,
|
|
48
|
+
) -> tuple[str, dict[str, str]]:
|
|
49
|
+
inc_schemas = sorted(_normalized_set(include_schemas))
|
|
50
|
+
exc_schemas = sorted(_normalized_set(exclude_schemas))
|
|
51
|
+
inc_objects = _split_qualified(_normalized_set(include_objects))
|
|
52
|
+
exc_objects = _split_qualified(_normalized_set(exclude_objects))
|
|
53
|
+
|
|
54
|
+
params: dict[str, str] = {}
|
|
55
|
+
clauses: list[str] = []
|
|
56
|
+
|
|
57
|
+
if inc_schemas:
|
|
58
|
+
names: list[str] = []
|
|
59
|
+
for i, schema in enumerate(inc_schemas):
|
|
60
|
+
key = f'inc_schema_{i}'
|
|
61
|
+
params[key] = schema
|
|
62
|
+
names.append(f':{key}')
|
|
63
|
+
clauses.append(f'lower(s.name) in ({", ".join(names)})')
|
|
64
|
+
|
|
65
|
+
if exc_schemas:
|
|
66
|
+
names = []
|
|
67
|
+
for i, schema in enumerate(exc_schemas):
|
|
68
|
+
key = f'exc_schema_{i}'
|
|
69
|
+
params[key] = schema
|
|
70
|
+
names.append(f':{key}')
|
|
71
|
+
clauses.append(f'lower(s.name) not in ({", ".join(names)})')
|
|
72
|
+
|
|
73
|
+
if inc_objects:
|
|
74
|
+
parts: list[str] = []
|
|
75
|
+
for i, (schema, name) in enumerate(inc_objects):
|
|
76
|
+
sk = f'inc_obj_schema_{i}'
|
|
77
|
+
nk = f'inc_obj_name_{i}'
|
|
78
|
+
params[sk] = schema
|
|
79
|
+
params[nk] = name
|
|
80
|
+
parts.append(f'(lower(s.name) = :{sk} and lower(o.name) = :{nk})')
|
|
81
|
+
clauses.append(f'({" or ".join(parts)})')
|
|
82
|
+
|
|
83
|
+
if exc_objects:
|
|
84
|
+
parts = []
|
|
85
|
+
for i, (schema, name) in enumerate(exc_objects):
|
|
86
|
+
sk = f'exc_obj_schema_{i}'
|
|
87
|
+
nk = f'exc_obj_name_{i}'
|
|
88
|
+
params[sk] = schema
|
|
89
|
+
params[nk] = name
|
|
90
|
+
parts.append(f'(lower(s.name) = :{sk} and lower(o.name) = :{nk})')
|
|
91
|
+
clauses.append(f'not ({" or ".join(parts)})')
|
|
92
|
+
|
|
93
|
+
if not clauses:
|
|
94
|
+
return '', {}
|
|
95
|
+
|
|
96
|
+
return '\n and ' + '\n and '.join(clauses), params
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _inject_filters(sql: str, filters_sql: str) -> str:
|
|
100
|
+
if not filters_sql:
|
|
101
|
+
return sql
|
|
102
|
+
return sql.replace(
|
|
103
|
+
'where o.is_ms_shipped = 0', f'where o.is_ms_shipped = 0{filters_sql}'
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def get_functions(
|
|
108
|
+
sql_client: UnifiedSQLClient,
|
|
109
|
+
*,
|
|
110
|
+
include_schemas: set[str] | None = None,
|
|
111
|
+
exclude_schemas: set[str] | None = None,
|
|
112
|
+
include_objects: set[str] | None = None,
|
|
113
|
+
exclude_objects: set[str] | None = None,
|
|
114
|
+
) -> list[SqlObjectDef]:
|
|
115
|
+
filters_sql, params = _build_filter_sql_and_params(
|
|
116
|
+
include_schemas=include_schemas,
|
|
117
|
+
exclude_schemas=exclude_schemas,
|
|
118
|
+
include_objects=include_objects,
|
|
119
|
+
exclude_objects=exclude_objects,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
rows = sql_client.execute_command_with_result_to_dicts(
|
|
123
|
+
_inject_filters(_SQL_FUNCTIONS, filters_sql), params
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
return [
|
|
127
|
+
SqlObjectDef(
|
|
128
|
+
schema_name=str(r['schema_name']),
|
|
129
|
+
object_name=str(r['object_name']),
|
|
130
|
+
definition=str(r['definition'] or ''),
|
|
131
|
+
)
|
|
132
|
+
for r in rows
|
|
133
|
+
]
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from al_data_utils.sql_utils.sql_utils import UnifiedSQLClient
|
|
4
|
+
from ..models import IndexDef
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
_SQL_INDEXES = r"""
|
|
8
|
+
with idx as (
|
|
9
|
+
select
|
|
10
|
+
s.name as schema_name,
|
|
11
|
+
t.name as table_name,
|
|
12
|
+
i.name as index_name,
|
|
13
|
+
i.index_id,
|
|
14
|
+
i.is_unique,
|
|
15
|
+
i.type_desc,
|
|
16
|
+
i.has_filter,
|
|
17
|
+
i.filter_definition,
|
|
18
|
+
i.is_disabled,
|
|
19
|
+
i.is_hypothetical
|
|
20
|
+
from sys.indexes i
|
|
21
|
+
inner join sys.tables t on t.object_id = i.object_id
|
|
22
|
+
inner join sys.schemas s on s.schema_id = t.schema_id
|
|
23
|
+
where i.type_desc <> 'heap'
|
|
24
|
+
and i.name is not null
|
|
25
|
+
and i.is_primary_key = 0
|
|
26
|
+
and i.is_unique_constraint = 0
|
|
27
|
+
and t.is_ms_shipped = 0
|
|
28
|
+
)
|
|
29
|
+
select
|
|
30
|
+
idx.schema_name,
|
|
31
|
+
idx.table_name,
|
|
32
|
+
idx.index_name,
|
|
33
|
+
cast(idx.is_unique as bit) as is_unique,
|
|
34
|
+
idx.type_desc,
|
|
35
|
+
cast(idx.has_filter as bit) as has_filter,
|
|
36
|
+
idx.filter_definition,
|
|
37
|
+
cast(idx.is_disabled as bit) as is_disabled,
|
|
38
|
+
cast(idx.is_hypothetical as bit) as is_hypothetical,
|
|
39
|
+
|
|
40
|
+
stuff((
|
|
41
|
+
select
|
|
42
|
+
', ' + quotename(c.name) + case when ic.is_descending_key = 1 then ' desc' else ' asc' end
|
|
43
|
+
from sys.index_columns ic
|
|
44
|
+
inner join sys.columns c
|
|
45
|
+
on c.object_id = ic.object_id and c.column_id = ic.column_id
|
|
46
|
+
where ic.object_id = object_id(quotename(idx.schema_name) + '.' + quotename(idx.table_name))
|
|
47
|
+
and ic.index_id = idx.index_id
|
|
48
|
+
and ic.is_included_column = 0
|
|
49
|
+
order by ic.key_ordinal
|
|
50
|
+
for xml path(''), type
|
|
51
|
+
).value('.', 'nvarchar(max)'), 1, 2, '') as key_columns,
|
|
52
|
+
|
|
53
|
+
stuff((
|
|
54
|
+
select
|
|
55
|
+
', ' + quotename(c.name)
|
|
56
|
+
from sys.index_columns ic
|
|
57
|
+
inner join sys.columns c
|
|
58
|
+
on c.object_id = ic.object_id and c.column_id = ic.column_id
|
|
59
|
+
where ic.object_id = object_id(quotename(idx.schema_name) + '.' + quotename(idx.table_name))
|
|
60
|
+
and ic.index_id = idx.index_id
|
|
61
|
+
and ic.is_included_column = 1
|
|
62
|
+
order by ic.index_column_id
|
|
63
|
+
for xml path(''), type
|
|
64
|
+
).value('.', 'nvarchar(max)'), 1, 2, '') as include_columns
|
|
65
|
+
from idx
|
|
66
|
+
order by idx.schema_name, idx.table_name, idx.index_name;
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _normalized_set(values: set[str] | None) -> set[str]:
|
|
71
|
+
if not values:
|
|
72
|
+
return set()
|
|
73
|
+
return {str(v).strip().lower() for v in values if str(v).strip()}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _split_qualified(values: set[str]) -> list[tuple[str, str]]:
|
|
77
|
+
pairs: list[tuple[str, str]] = []
|
|
78
|
+
for v in sorted(values):
|
|
79
|
+
if '.' not in v:
|
|
80
|
+
continue
|
|
81
|
+
schema, table = v.split('.', 1)
|
|
82
|
+
schema = schema.strip().lower()
|
|
83
|
+
table = table.strip().lower()
|
|
84
|
+
if schema and table:
|
|
85
|
+
pairs.append((schema, table))
|
|
86
|
+
return pairs
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _build_filter_sql_and_params(
|
|
90
|
+
*,
|
|
91
|
+
include_schemas: set[str] | None = None,
|
|
92
|
+
exclude_schemas: set[str] | None = None,
|
|
93
|
+
include_tables: set[str] | None = None,
|
|
94
|
+
exclude_tables: set[str] | None = None,
|
|
95
|
+
) -> tuple[str, dict[str, str]]:
|
|
96
|
+
inc_schemas = sorted(_normalized_set(include_schemas))
|
|
97
|
+
exc_schemas = sorted(_normalized_set(exclude_schemas))
|
|
98
|
+
inc_tables = _split_qualified(_normalized_set(include_tables))
|
|
99
|
+
exc_tables = _split_qualified(_normalized_set(exclude_tables))
|
|
100
|
+
|
|
101
|
+
params: dict[str, str] = {}
|
|
102
|
+
clauses: list[str] = []
|
|
103
|
+
|
|
104
|
+
if inc_schemas:
|
|
105
|
+
names: list[str] = []
|
|
106
|
+
for i, schema in enumerate(inc_schemas):
|
|
107
|
+
key = f'inc_schema_{i}'
|
|
108
|
+
params[key] = schema
|
|
109
|
+
names.append(f':{key}')
|
|
110
|
+
clauses.append(f'lower(s.name) in ({", ".join(names)})')
|
|
111
|
+
|
|
112
|
+
if exc_schemas:
|
|
113
|
+
names = []
|
|
114
|
+
for i, schema in enumerate(exc_schemas):
|
|
115
|
+
key = f'exc_schema_{i}'
|
|
116
|
+
params[key] = schema
|
|
117
|
+
names.append(f':{key}')
|
|
118
|
+
clauses.append(f'lower(s.name) not in ({", ".join(names)})')
|
|
119
|
+
|
|
120
|
+
if inc_tables:
|
|
121
|
+
parts: list[str] = []
|
|
122
|
+
for i, (schema, table) in enumerate(inc_tables):
|
|
123
|
+
sk = f'inc_tbl_schema_{i}'
|
|
124
|
+
tk = f'inc_tbl_name_{i}'
|
|
125
|
+
params[sk] = schema
|
|
126
|
+
params[tk] = table
|
|
127
|
+
parts.append(f'(lower(s.name) = :{sk} and lower(t.name) = :{tk})')
|
|
128
|
+
clauses.append(f'({" or ".join(parts)})')
|
|
129
|
+
|
|
130
|
+
if exc_tables:
|
|
131
|
+
parts = []
|
|
132
|
+
for i, (schema, table) in enumerate(exc_tables):
|
|
133
|
+
sk = f'exc_tbl_schema_{i}'
|
|
134
|
+
tk = f'exc_tbl_name_{i}'
|
|
135
|
+
params[sk] = schema
|
|
136
|
+
params[tk] = table
|
|
137
|
+
parts.append(f'(lower(s.name) = :{sk} and lower(t.name) = :{tk})')
|
|
138
|
+
clauses.append(f'not ({" or ".join(parts)})')
|
|
139
|
+
|
|
140
|
+
if not clauses:
|
|
141
|
+
return '', {}
|
|
142
|
+
|
|
143
|
+
return '\n and ' + '\n and '.join(clauses), params
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _inject_filters(sql: str, filters_sql: str) -> str:
|
|
147
|
+
if not filters_sql:
|
|
148
|
+
return sql
|
|
149
|
+
return sql.replace(
|
|
150
|
+
'and t.is_ms_shipped = 0', f'and t.is_ms_shipped = 0{filters_sql}'
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def get_indexes(
|
|
155
|
+
sql_client: UnifiedSQLClient,
|
|
156
|
+
*,
|
|
157
|
+
include_schemas: set[str] | None = None,
|
|
158
|
+
exclude_schemas: set[str] | None = None,
|
|
159
|
+
include_tables: set[str] | None = None,
|
|
160
|
+
exclude_tables: set[str] | None = None,
|
|
161
|
+
) -> list[IndexDef]:
|
|
162
|
+
filters_sql, params = _build_filter_sql_and_params(
|
|
163
|
+
include_schemas=include_schemas,
|
|
164
|
+
exclude_schemas=exclude_schemas,
|
|
165
|
+
include_tables=include_tables,
|
|
166
|
+
exclude_tables=exclude_tables,
|
|
167
|
+
)
|
|
168
|
+
rows = sql_client.execute_command_with_result_to_dicts(
|
|
169
|
+
_inject_filters(_SQL_INDEXES, filters_sql), params
|
|
170
|
+
)
|
|
171
|
+
result: list[IndexDef] = []
|
|
172
|
+
for r in rows:
|
|
173
|
+
result.append(
|
|
174
|
+
IndexDef(
|
|
175
|
+
schema_name=str(r['schema_name']),
|
|
176
|
+
table_name=str(r['table_name']),
|
|
177
|
+
index_name=str(r['index_name']),
|
|
178
|
+
is_unique=bool(r['is_unique']),
|
|
179
|
+
type_desc=str(r['type_desc']),
|
|
180
|
+
has_filter=bool(r['has_filter']),
|
|
181
|
+
filter_definition=None
|
|
182
|
+
if r['filter_definition'] is None
|
|
183
|
+
else str(r['filter_definition']),
|
|
184
|
+
is_disabled=bool(r['is_disabled']),
|
|
185
|
+
is_hypothetical=bool(r['is_hypothetical']),
|
|
186
|
+
key_columns=str(r['key_columns'] or ''),
|
|
187
|
+
include_columns=str(r['include_columns'] or ''),
|
|
188
|
+
)
|
|
189
|
+
)
|
|
190
|
+
return result
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
|
|
5
|
+
from al_data_utils.sql_utils.sql_utils import UnifiedSQLClient
|
|
6
|
+
from ..models import SqlObjectDef
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
_SQL_SEQUENCES = r"""
|
|
10
|
+
select
|
|
11
|
+
s.name as schema_name,
|
|
12
|
+
seq.name as object_name,
|
|
13
|
+
ty.name as data_type,
|
|
14
|
+
convert(nvarchar(100), seq.start_value) as start_value,
|
|
15
|
+
convert(nvarchar(100), seq.increment) as increment_value,
|
|
16
|
+
convert(nvarchar(100), seq.minimum_value) as minimum_value,
|
|
17
|
+
convert(nvarchar(100), seq.maximum_value) as maximum_value,
|
|
18
|
+
cast(seq.is_cycling as bit) as is_cycling,
|
|
19
|
+
cast(seq.is_cached as bit) as is_cached,
|
|
20
|
+
cast(seq.cache_size as bigint) as cache_size
|
|
21
|
+
from sys.sequences seq
|
|
22
|
+
inner join sys.schemas s
|
|
23
|
+
on s.schema_id = seq.schema_id
|
|
24
|
+
inner join sys.types ty
|
|
25
|
+
on ty.user_type_id = seq.user_type_id
|
|
26
|
+
order by s.name, seq.name;
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _normalized_set(values: set[str] | None) -> set[str]:
|
|
31
|
+
if not values:
|
|
32
|
+
return set()
|
|
33
|
+
return {str(v).strip().lower() for v in values if str(v).strip()}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _split_qualified(values: set[str]) -> list[tuple[str, str]]:
|
|
37
|
+
pairs: list[tuple[str, str]] = []
|
|
38
|
+
for v in sorted(values):
|
|
39
|
+
if '.' not in v:
|
|
40
|
+
continue
|
|
41
|
+
schema, name = v.split('.', 1)
|
|
42
|
+
schema = schema.strip().lower()
|
|
43
|
+
name = name.strip().lower()
|
|
44
|
+
if schema and name:
|
|
45
|
+
pairs.append((schema, name))
|
|
46
|
+
return pairs
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _build_filter_sql_and_params(
|
|
50
|
+
*,
|
|
51
|
+
include_schemas: set[str] | None = None,
|
|
52
|
+
exclude_schemas: set[str] | None = None,
|
|
53
|
+
include_objects: set[str] | None = None,
|
|
54
|
+
exclude_objects: set[str] | None = None,
|
|
55
|
+
) -> tuple[str, dict[str, str]]:
|
|
56
|
+
inc_schemas = sorted(_normalized_set(include_schemas))
|
|
57
|
+
exc_schemas = sorted(_normalized_set(exclude_schemas))
|
|
58
|
+
inc_objects = _split_qualified(_normalized_set(include_objects))
|
|
59
|
+
exc_objects = _split_qualified(_normalized_set(exclude_objects))
|
|
60
|
+
|
|
61
|
+
params: dict[str, str] = {}
|
|
62
|
+
clauses: list[str] = []
|
|
63
|
+
|
|
64
|
+
if inc_schemas:
|
|
65
|
+
names: list[str] = []
|
|
66
|
+
for i, schema in enumerate(inc_schemas):
|
|
67
|
+
key = f'inc_schema_{i}'
|
|
68
|
+
params[key] = schema
|
|
69
|
+
names.append(f':{key}')
|
|
70
|
+
clauses.append(f'lower(s.name) in ({", ".join(names)})')
|
|
71
|
+
|
|
72
|
+
if exc_schemas:
|
|
73
|
+
names = []
|
|
74
|
+
for i, schema in enumerate(exc_schemas):
|
|
75
|
+
key = f'exc_schema_{i}'
|
|
76
|
+
params[key] = schema
|
|
77
|
+
names.append(f':{key}')
|
|
78
|
+
clauses.append(f'lower(s.name) not in ({", ".join(names)})')
|
|
79
|
+
|
|
80
|
+
if inc_objects:
|
|
81
|
+
parts: list[str] = []
|
|
82
|
+
for i, (schema, name) in enumerate(inc_objects):
|
|
83
|
+
sk = f'inc_obj_schema_{i}'
|
|
84
|
+
nk = f'inc_obj_name_{i}'
|
|
85
|
+
params[sk] = schema
|
|
86
|
+
params[nk] = name
|
|
87
|
+
parts.append(f'(lower(s.name) = :{sk} and lower(seq.name) = :{nk})')
|
|
88
|
+
clauses.append(f'({" or ".join(parts)})')
|
|
89
|
+
|
|
90
|
+
if exc_objects:
|
|
91
|
+
parts = []
|
|
92
|
+
for i, (schema, name) in enumerate(exc_objects):
|
|
93
|
+
sk = f'exc_obj_schema_{i}'
|
|
94
|
+
nk = f'exc_obj_name_{i}'
|
|
95
|
+
params[sk] = schema
|
|
96
|
+
params[nk] = name
|
|
97
|
+
parts.append(f'(lower(s.name) = :{sk} and lower(seq.name) = :{nk})')
|
|
98
|
+
clauses.append(f'not ({" or ".join(parts)})')
|
|
99
|
+
|
|
100
|
+
if not clauses:
|
|
101
|
+
return '', {}
|
|
102
|
+
|
|
103
|
+
return '\nwhere ' + '\n and '.join(clauses), params
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _inject_filters(sql: str, filters_sql: str) -> str:
|
|
107
|
+
if not filters_sql:
|
|
108
|
+
return sql
|
|
109
|
+
return sql.replace(
|
|
110
|
+
'order by s.name, seq.name;', f'{filters_sql}\norder by s.name, seq.name;'
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _emit_sequence_ddl(r: Mapping[str, object]) -> str:
|
|
115
|
+
schema_name = str(r['schema_name'])
|
|
116
|
+
object_name = str(r['object_name'])
|
|
117
|
+
data_type = str(r['data_type'])
|
|
118
|
+
start_value = str(r.get('start_value') or '1')
|
|
119
|
+
increment_value = str(r.get('increment_value') or '1')
|
|
120
|
+
minimum_value = str(r.get('minimum_value') or '')
|
|
121
|
+
maximum_value = str(r.get('maximum_value') or '')
|
|
122
|
+
is_cycling = bool(r.get('is_cycling'))
|
|
123
|
+
is_cached = bool(r.get('is_cached'))
|
|
124
|
+
cache_size_raw = r.get('cache_size')
|
|
125
|
+
|
|
126
|
+
parts: list[str] = [
|
|
127
|
+
f'create sequence {schema_name}.{object_name}',
|
|
128
|
+
f' as {data_type}',
|
|
129
|
+
f' start with {start_value}',
|
|
130
|
+
f' increment by {increment_value}',
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
if minimum_value:
|
|
134
|
+
parts.append(f' minvalue {minimum_value}')
|
|
135
|
+
else:
|
|
136
|
+
parts.append(' no minvalue')
|
|
137
|
+
|
|
138
|
+
if maximum_value:
|
|
139
|
+
parts.append(f' maxvalue {maximum_value}')
|
|
140
|
+
else:
|
|
141
|
+
parts.append(' no maxvalue')
|
|
142
|
+
|
|
143
|
+
parts.append(' cycle' if is_cycling else ' no cycle')
|
|
144
|
+
|
|
145
|
+
if is_cached and cache_size_raw is not None:
|
|
146
|
+
cache_size = int(str(cache_size_raw))
|
|
147
|
+
parts.append(f' cache {cache_size}')
|
|
148
|
+
else:
|
|
149
|
+
parts.append(' no cache')
|
|
150
|
+
|
|
151
|
+
return '\n'.join(parts)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def get_sequences(
|
|
155
|
+
sql_client: UnifiedSQLClient,
|
|
156
|
+
*,
|
|
157
|
+
include_schemas: set[str] | None = None,
|
|
158
|
+
exclude_schemas: set[str] | None = None,
|
|
159
|
+
include_objects: set[str] | None = None,
|
|
160
|
+
exclude_objects: set[str] | None = None,
|
|
161
|
+
) -> list[SqlObjectDef]:
|
|
162
|
+
filters_sql, params = _build_filter_sql_and_params(
|
|
163
|
+
include_schemas=include_schemas,
|
|
164
|
+
exclude_schemas=exclude_schemas,
|
|
165
|
+
include_objects=include_objects,
|
|
166
|
+
exclude_objects=exclude_objects,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
rows = sql_client.execute_command_with_result_to_dicts(
|
|
170
|
+
_inject_filters(_SQL_SEQUENCES, filters_sql), params
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
return [
|
|
174
|
+
SqlObjectDef(
|
|
175
|
+
schema_name=str(r['schema_name']),
|
|
176
|
+
object_name=str(r['object_name']),
|
|
177
|
+
definition=_emit_sequence_ddl(r),
|
|
178
|
+
)
|
|
179
|
+
for r in rows
|
|
180
|
+
]
|