Skip to content

Commit a1622ea

Browse files
committed
insert and update from BaseModel
1 parent 545f857 commit a1622ea

10 files changed

Lines changed: 231 additions & 66 deletions

File tree

abstra_json_sql/apply.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,9 @@ def apply_expression(expression: Expression, ctx: dict):
267267
)
268268
)
269269
elif expression.name.lower() == "bool_or":
270-
assert (
271-
len(expression.args) == 1
272-
), "Bool_or function requires one argument"
270+
assert len(expression.args) == 1, (
271+
"Bool_or function requires one argument"
272+
)
273273
return any(
274274
apply_expression(expression.args[0], {**ctx, **row})
275275
for row in ctx["__grouped_rows"]
@@ -279,9 +279,9 @@ def apply_expression(expression: Expression, ctx: dict):
279279
)
280280
)
281281
elif expression.name.lower() == "bool_and":
282-
assert (
283-
len(expression.args) == 1
284-
), "Bool_and function requires one argument"
282+
assert len(expression.args) == 1, (
283+
"Bool_and function requires one argument"
284+
)
285285
return all(
286286
apply_expression(expression.args[0], {**ctx, **row})
287287
for row in ctx["__grouped_rows"]
@@ -291,9 +291,9 @@ def apply_expression(expression: Expression, ctx: dict):
291291
)
292292
)
293293
elif expression.name.lower() == "bit_or":
294-
assert (
295-
len(expression.args) == 1
296-
), "Bit_or function requires one argument"
294+
assert len(expression.args) == 1, (
295+
"Bit_or function requires one argument"
296+
)
297297
not_null_rows = [
298298
row
299299
for row in ctx["__grouped_rows"]
@@ -309,9 +309,9 @@ def apply_expression(expression: Expression, ctx: dict):
309309
result_bits |= apply_expression(expression.args[0], {**ctx, **row})
310310
return result_bits
311311
elif expression.name.lower() == "bit_and":
312-
assert (
313-
len(expression.args) == 1
314-
), "Bit_and function requires one argument"
312+
assert len(expression.args) == 1, (
313+
"Bit_and function requires one argument"
314+
)
315315
not_null_rows = [
316316
row
317317
for row in ctx["__grouped_rows"]
@@ -327,17 +327,17 @@ def apply_expression(expression: Expression, ctx: dict):
327327
result_bits &= apply_expression(expression.args[0], {**ctx, **row})
328328
return result_bits
329329
elif expression.name.lower() == "array_agg":
330-
assert (
331-
len(expression.args) == 1
332-
), "Array_agg function requires one argument"
330+
assert len(expression.args) == 1, (
331+
"Array_agg function requires one argument"
332+
)
333333
return [
334334
apply_expression(expression.args[0], {**ctx, **row})
335335
for row in ctx["__grouped_rows"]
336336
]
337337
elif expression.name.lower() == "string_agg":
338-
assert (
339-
len(expression.args) == 2
340-
), "String_agg function requires two arguments"
338+
assert len(expression.args) == 2, (
339+
"String_agg function requires two arguments"
340+
)
341341
separator = apply_expression(expression.args[1], ctx)
342342
return separator.join(
343343
str(apply_expression(expression.args[0], {**ctx, **row}))
@@ -350,14 +350,14 @@ def apply_expression(expression: Expression, ctx: dict):
350350
else:
351351
args = [apply_expression(arg, ctx) for arg in expression.args]
352352
if expression.name == "lower":
353-
assert isinstance(
354-
args[0], str
355-
), "lower function requires a string argument"
353+
assert isinstance(args[0], str), (
354+
"lower function requires a string argument"
355+
)
356356
return args[0].lower()
357357
elif expression.name == "upper":
358-
assert isinstance(
359-
args[0], str
360-
), "upper function requires a string argument"
358+
assert isinstance(args[0], str), (
359+
"upper function requires a string argument"
360+
)
361361
return args[0].upper()
362362
else:
363363
raise ValueError(f"Unknown function: {expression.name}")

abstra_json_sql/parser.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -435,9 +435,9 @@ def parse_fields(tokens: List[Token]) -> Tuple[List[SelectField], List[Token]]:
435435
):
436436
tokens = tokens[1:]
437437
alias_token = tokens[0]
438-
assert (
439-
alias_token.type == "name"
440-
), f"Expected alias name, got {alias_token}"
438+
assert alias_token.type == "name", (
439+
f"Expected alias name, got {alias_token}"
440+
)
441441
field.alias = alias_token.value
442442
tokens = tokens[1:]
443443
fields.append(field)
@@ -668,9 +668,9 @@ def parse_update(tokens: List[Token]) -> Tuple[Ast, List[Token]]:
668668
else:
669669
table_alias = None
670670

671-
assert (
672-
tokens[0].type == "keyword" and tokens[0].value.upper() == "SET"
673-
), f"Expecting SET assignments, got '{tokens[0].value}'"
671+
assert tokens[0].type == "keyword" and tokens[0].value.upper() == "SET", (
672+
f"Expecting SET assignments, got '{tokens[0].value}'"
673+
)
674674
tokens = tokens[1:]
675675

676676
changes = []
@@ -754,9 +754,9 @@ def parse_with(tokens: List[Token]) -> Tuple[Optional[Ast], List[Token]]:
754754
tokens = tokens[1:]
755755

756756
as_token = tokens[0]
757-
assert (
758-
as_token.type == "keyword" and as_token.value.upper() == "AS"
759-
), f"Expected AS, got {as_token}"
757+
assert as_token.type == "keyword" and as_token.value.upper() == "AS", (
758+
f"Expected AS, got {as_token}"
759+
)
760760
tokens = tokens[1:]
761761

762762
cmd, tokens = parse_expression(tokens)

abstra_json_sql/persistence/extended.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def change_column_type(
100100
return
101101
self.snapshot.change_column_type(table_name, column_name, new_type)
102102

103-
def insert(self, table_name: str, row: dict):
103+
def _insert(self, table_name: str, row: dict):
104104
for table in self.extra_tables:
105105
if table.name == table_name:
106106
# Convert row from column names to column IDs
@@ -109,7 +109,7 @@ def insert(self, table_name: str, row: dict):
109109
return
110110
self.snapshot.insert(table_name, row)
111111

112-
def update(self, table_name, idx, changes):
112+
def _update(self, table_name, idx, changes):
113113
for table in self.extra_tables:
114114
if table.name == table_name:
115115
# Convert changes from column names to column IDs
@@ -118,7 +118,7 @@ def update(self, table_name, idx, changes):
118118
return
119119
self.snapshot.update(table_name, idx, changes)
120120

121-
def delete(self, table_name: str, idxs: List[int]):
121+
def _delete(self, table_name: str, idxs: List[int]):
122122
for table in self.extra_tables:
123123
if table.name == table_name:
124124
# Sort indices in descending order to avoid index shifting

abstra_json_sql/persistence/json.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def rename_table(self, old_name: str, new_name: str):
152152
# Update metadata with new name
153153
self._save_table_metadata(table_id, new_name, columns)
154154

155-
def insert(self, table_name: str, row: dict):
155+
def _insert(self, table_name: str, row: dict):
156156
table_id, columns = self._get_table_metadata_by_name(table_name)
157157
if table_id is None:
158158
raise ValueError(f"Table {table_name} not found")
@@ -165,9 +165,9 @@ def insert(self, table_name: str, row: dict):
165165
temp_table = Table(name=table_name, columns=columns, data=[], table_id=table_id)
166166

167167
rows = json.loads(table_path.read_text())
168-
assert isinstance(
169-
rows, list
170-
), f"File {table_path} does not contain a list of rows"
168+
assert isinstance(rows, list), (
169+
f"File {table_path} does not contain a list of rows"
170+
)
171171

172172
# Convert row to column ID format
173173
row_with_ids = temp_table.convert_row_to_column_ids(row)
@@ -184,9 +184,9 @@ def add_column(self, table_name: str, column: Column):
184184
raise FileNotFoundError(f"File {table_path} does not exist")
185185

186186
rows = json.loads(table_path.read_text())
187-
assert isinstance(
188-
rows, list
189-
), f"File {table_path} does not contain a list of rows"
187+
assert isinstance(rows, list), (
188+
f"File {table_path} does not contain a list of rows"
189+
)
190190

191191
# Check if column already exists
192192
if any(col.name == column.name for col in existing_columns):
@@ -213,9 +213,9 @@ def remove_column(self, table_name: str, column_name: str):
213213
raise FileNotFoundError(f"File {table_path} does not exist")
214214

215215
rows = json.loads(table_path.read_text())
216-
assert isinstance(
217-
rows, list
218-
), f"File {table_path} does not contain a list of rows"
216+
assert isinstance(rows, list), (
217+
f"File {table_path} does not contain a list of rows"
218+
)
219219

220220
# Remove column from data using column ID
221221
column_to_remove = None
@@ -244,9 +244,9 @@ def rename_column(self, table_name: str, old_name: str, new_name: str):
244244
raise FileNotFoundError(f"File {table_path} does not exist")
245245

246246
rows = json.loads(table_path.read_text())
247-
assert isinstance(
248-
rows, list
249-
), f"File {table_path} does not contain a list of rows"
247+
assert isinstance(rows, list), (
248+
f"File {table_path} does not contain a list of rows"
249+
)
250250

251251
# Data doesn't need to change for rename_column since we use column IDs
252252
# Only metadata needs to be updated
@@ -271,7 +271,7 @@ def change_column_type(
271271
raise ValueError(f"Column {column_name} not found in table {table_name}")
272272
self._save_table_metadata(table_id, table_name, columns)
273273

274-
def update(self, table_name: str, idx: int, changes: dict):
274+
def _update(self, table_name: str, idx: int, changes: dict):
275275
table_id, columns = self._get_table_metadata_by_name(table_name)
276276
if table_id is None:
277277
raise ValueError(f"Table {table_name} not found")
@@ -284,9 +284,9 @@ def update(self, table_name: str, idx: int, changes: dict):
284284
temp_table = Table(name=table_name, columns=columns, data=[], table_id=table_id)
285285

286286
rows = json.loads(table_path.read_text())
287-
assert isinstance(
288-
rows, list
289-
), f"File {table_path} does not contain a list of rows"
287+
assert isinstance(rows, list), (
288+
f"File {table_path} does not contain a list of rows"
289+
)
290290
if idx < 0 or idx >= len(rows):
291291
raise IndexError(f"Index {idx} out of range for table {table_name}")
292292

@@ -295,7 +295,7 @@ def update(self, table_name: str, idx: int, changes: dict):
295295
rows[idx].update(changes_with_ids)
296296
table_path.write_text(json.dumps(rows, indent=2))
297297

298-
def delete(self, table_name: str, idxs: List[int]):
298+
def _delete(self, table_name: str, idxs: List[int]):
299299
table_id, _ = self._get_table_metadata_by_name(table_name)
300300
if table_id is None:
301301
raise ValueError(f"Table {table_name} not found")
@@ -305,9 +305,9 @@ def delete(self, table_name: str, idxs: List[int]):
305305
raise FileNotFoundError(f"File {table_path} does not exist")
306306

307307
rows = json.loads(table_path.read_text())
308-
assert isinstance(
309-
rows, list
310-
), f"File {table_path} does not contain a list of rows"
308+
assert isinstance(rows, list), (
309+
f"File {table_path} does not contain a list of rows"
310+
)
311311

312312
# Sort indices in descending order to avoid index shifting
313313
for idx in sorted(idxs, reverse=True):

abstra_json_sql/persistence/jsonl.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ def change_column_type(
296296
raise ValueError(f"Column {column_name} not found in table {table_name}")
297297
self._save_table_metadata(table_id, table_name, columns)
298298

299-
def insert(self, table_name: str, row: dict):
299+
def _insert(self, table_name: str, row: dict):
300300
table_id, columns = self._get_table_metadata_by_name(table_name)
301301
if table_id is None:
302302
raise ValueError(f"Table {table_name} not found")
@@ -310,7 +310,7 @@ def insert(self, table_name: str, row: dict):
310310
row_with_ids = temp_table.convert_row_to_column_ids(row)
311311
f.write(json.dumps(row_with_ids) + "\n")
312312

313-
def update(self, table_name: str, idx: int, changes: dict):
313+
def _update(self, table_name: str, idx: int, changes: dict):
314314
table_id, columns = self._get_table_metadata_by_name(table_name)
315315
if table_id is None:
316316
raise ValueError(f"Table {table_name} not found")
@@ -340,7 +340,7 @@ def update(self, table_name: str, idx: int, changes: dict):
340340
for row in rows:
341341
f.write(json.dumps(row) + "\n")
342342

343-
def delete(self, table_name: str, idxs: List[int]):
343+
def _delete(self, table_name: str, idxs: List[int]):
344344
table_id, _ = self._get_table_metadata_by_name(table_name)
345345
if table_id is None:
346346
raise ValueError(f"Table {table_name} not found")

abstra_json_sql/persistence/memory.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33

44

55
class InMemoryTables(ITablesSnapshot):
6+
def _update(self, table: str, idx: int, changes: dict):
7+
table_obj = self._get_internal_table(table)
8+
if table_obj is None:
9+
raise ValueError(f"Table {table} not found")
10+
# Convert changes from column names to column IDs
11+
changes_with_ids = table_obj.convert_row_to_column_ids(changes)
12+
table_obj.data[idx].update(changes_with_ids)
13+
14+
def _delete(self, table: str, idxs: List[int]):
15+
table_obj = self._get_internal_table(table)
16+
if table_obj is None:
17+
raise ValueError(f"Table {table} not found")
18+
table_obj.data = [row for i, row in enumerate(table_obj.data) if i not in idxs]
19+
620
def __init__(self, tables: List[Table] = None):
721
if tables is None:
822
self.tables = []
@@ -125,7 +139,7 @@ def change_column_type(
125139
raise ValueError(f"Column {column_name} not found in table {table_name}")
126140
column.schema = new_type
127141

128-
def insert(self, table: str, row: dict):
142+
def _insert(self, table: str, row: dict):
129143
table_obj = self._get_internal_table(table)
130144
if table_obj is None:
131145
raise ValueError(f"Table {table} not found")

abstra_json_sql/string_utils.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import re
2+
3+
4+
def snake_case(name: str) -> str:
5+
"""Convert a string to snake_case."""
6+
s = re.sub(r"[\s\-]+", "_", name)
7+
s = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", s)
8+
s = re.sub(r"([a-zA-Z])([0-9])", r"\1_\2", s)
9+
s = re.sub(r"([0-9])([a-zA-Z])", r"\1_\2", s)
10+
return s.lower()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from unittest import TestCase, main
2+
from abstra_json_sql.string_utils import snake_case
3+
4+
5+
class TestSnakeCaseUtils(TestCase):
6+
def test_snake_case(self):
7+
self.assertEqual(snake_case("Hello World"), "hello_world")
8+
self.assertEqual(snake_case("snake_case"), "snake_case")
9+
self.assertEqual(snake_case("Test123"), "test_123")
10+
self.assertEqual(snake_case("test with spaces"), "test_with_spaces")
11+
self.assertEqual(snake_case("UPPERCASE"), "uppercase")
12+
13+
14+
if __name__ == "__main__":
15+
main()

0 commit comments

Comments
 (0)