44# License, v. 2.0. If a copy of the MPL was not distributed with this
55# file, You can obtain one at https://mozilla.org/MPL/2.0/.
66
7+ from __future__ import annotations
8+
79import argparse
810import logging
911import os
1012import sys
1113from datetime import datetime
12- from typing import List , Optional
14+ from typing import Any
1315
1416
15- from google .cloud import spanner
16- from google .cloud .spanner_v1 .database import Database
17- from google .cloud .spanner_v1 import param_types
17+ from google .cloud import spanner # type: ignore[attr-defined]
18+ from google .cloud .spanner_v1 import param_types as param_types
1819from statsd .defaults .env import statsd
1920
2021from tools .spanner .utils import ids_from_env , Mode
3132
3233
3334def deleter (
34- database : Database ,
35+ database : Any ,
3536 name : str ,
3637 query : str ,
37- prefix : Optional [str ] = None ,
38- params : Optional [dict ] = None ,
39- param_types : Optional [dict ] = None ,
40- dryrun : Optional [bool ] = False ,
41- ):
38+ prefix : str | None = None ,
39+ params : dict [str , Any ] | None = None ,
40+ param_types : dict [str , Any ] | None = None ,
41+ dryrun : bool | None = False ,
42+ ) -> None :
43+ """Execute a partitioned DML delete and emit statsd timing metrics."""
4244 with statsd .timer (f"syncstorage.purge_ttl.{ name } _duration" ):
4345 logging .info (f"Running: { query } :: { params } " )
4446 start = datetime .now ()
@@ -53,16 +55,23 @@ def deleter(
5355 )
5456
5557
56- def add_conditions (args , query : str , prefix : Optional [str ]):
57- """
58- Add SQL conditions to a query.
59- :param args: The program arguments
60- :param query: The SQL query
61- :param prefix: The current prefix, if given
62- :return: The updated SQL query, and list of params
58+ def add_conditions (
59+ args : argparse .Namespace ,
60+ query : str ,
61+ prefix : str | None ,
62+ ) -> tuple [str , dict [str , Any ], dict [str , Any ]]:
63+ """Add SQL conditions to a query based on collection IDs and UID prefix.
64+
65+ Args:
66+ args: Parsed command-line arguments.
67+ query: The base SQL query.
68+ prefix: Optional UID prefix to filter rows.
69+
70+ Returns:
71+ A 3-tuple of (updated query, params dict, param_types dict).
6372 """
64- params = {}
65- types = {}
73+ params : dict [ str , Any ] = {}
74+ types : dict [ str , Any ] = {}
6675 if args .collection_ids :
6776 ids = list (filter (len , args .collection_ids ))
6877 if ids :
@@ -84,12 +93,8 @@ def add_conditions(args, query: str, prefix: Optional[str]):
8493 return (query , params , types )
8594
8695
87- def get_expiry_condition (args ):
88- """
89- Get the expiry SQL WHERE condition to use
90- :param args: The program arguments
91- :return: A SQL snippet to use in the WHERE clause
92- """
96+ def get_expiry_condition (args : argparse .Namespace ) -> str :
97+ """Return the expiry WHERE condition SQL snippet for the given expiry mode."""
9398 if args .expiry_mode == "now" :
9499 return "expiry < CURRENT_TIMESTAMP()"
95100 elif args .expiry_mode == "midnight" :
@@ -98,14 +103,13 @@ def get_expiry_condition(args):
98103 raise Exception (f"Invalid expiry mode: { args .expiry_mode } " )
99104
100105
101- def spanner_purge (args ) -> None :
102- """
103- Purges expired TTL records from Spanner based on the provided arguments.
106+ def spanner_purge (args : argparse .Namespace ) -> None :
107+ """Purge expired TTL records from Spanner based on the provided arguments.
104108
105- This function connects to the specified Spanner instance and database,
106- determines the expiry condition, and deletes expired records from the
107- 'batches' and/or ' bsos' tables according to the purge mode. Supports
108- filtering by collection IDs and UID prefixes, and can operate in dry-run mode.
109+ Connects to the specified Spanner instance and database, determines the
110+ expiry condition, and deletes expired records from the 'batches' and/or
111+ 'bsos' tables. Supports filtering by collection IDs and UID prefixes,
112+ and can operate in dry-run mode.
109113
110114 Args:
111115 args (argparse.Namespace): Parsed command-line arguments containing
@@ -161,10 +165,12 @@ def spanner_purge(args) -> None:
161165 )
162166
163167
164- def get_args ():
165- """
166- Parses and returns command-line arguments for the Spanner TTL purge tool.
167- If a DSN URL is provided, usually `SYNC_SYNCSTORAGE__DATABASE_URL`, its values override the corresponding arguments.
168+ def get_args () -> argparse .Namespace :
169+ """Parse and return CLI arguments for the Spanner TTL purge tool.
170+
171+ If a DSN URL is provided via --sync_database_url or
172+ SYNC_SYNCSTORAGE__DATABASE_URL, its values override the corresponding
173+ instance_id, database_id, and project_id arguments.
168174
169175 Returns:
170176 argparse.Namespace: Parsed command-line arguments with the following attributes:
@@ -257,15 +263,14 @@ def get_args():
257263 return args
258264
259265
260- def parse_args_list (args_list : str ) -> List [str ]:
261- """
262- Parses a string representing a list of items into a list of strings.
266+ def parse_args_list (args_list : str ) -> list [str ]:
267+ """Parse a bracketed comma-separated string into a list of strings.
263268
264269 Args:
265- args_list (str) : String to parse, e.g., "[item1,item2,item3]" or "item1".
270+ args_list: String to parse, e.g., "[item1,item2,item3]" or "item1".
266271
267272 Returns:
268- List[str]: List of parsed string items.
273+ List of parsed string items.
269274 """
270275 if args_list [0 ] != "[" or args_list [- 1 ] != "]" :
271276 # Assume it's a single item
0 commit comments