Skip to content

Commit 11cdcef

Browse files
committed
refactor <action>_row() as counting rows wass not reliable, and other fixes
1 parent 4c8c473 commit 11cdcef

File tree

1 file changed

+52
-83
lines changed

1 file changed

+52
-83
lines changed

micropydatabase.py

Lines changed: 52 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ def update_row(self, row_id: int, update_data: any):
343343
"""
344344
# Check to make sure all the column names given by user
345345
# match the column names in the table.
346-
data = self.__scrub_data(update_data)
346+
data = self.__scrub_data(update_data, False)
347347
path = self.__data_file_for_row_id(row_id)
348348
if data:
349349
# Create a temp data file with the updated row data.
@@ -398,13 +398,11 @@ def find_row(self, row_id: int):
398398
# Calculate what line in the file the row_id will be found at
399399
looking_for_line = self.__row_id_in_file(row_id)
400400

401-
# Initiate line-counter
402-
current_line = 1
401+
# Prevous method of counting lines is not reliable
403402
with open(self.__data_file_for_row_id(row_id), 'r') as f:
404-
for line in f:
403+
for current_line, line in enumerate(f):
405404
if current_line == looking_for_line:
406405
return json.loads(line)
407-
current_line += 1
408406

409407
raise Exception("Could not find row_id {}".format(row_id))
410408

@@ -437,7 +435,7 @@ def scan(self, queries: any = None, show_row: bool = False):
437435
Iterate through the whole table and return data by line
438436
"""
439437
if queries:
440-
queries = self.__scrub_data(queries)
438+
queries = self.__scrub_data(queries, False)
441439
location = os.listdir(self.path)
442440
# Remove non-data files from our list of dirs.
443441
location = [element for element in location if 'data' in element]
@@ -448,18 +446,19 @@ def scan(self, queries: any = None, show_row: bool = False):
448446
for f in location:
449447
with open("{}/{}".format(self.path, f), 'r') as data:
450448
for line in data:
451-
current_data = json.loads(line)
452-
# If we are not searching for anything
453-
if not queries:
454-
if show_rows:
455-
current_data['d']["_row"] = current_data['r']
456-
yield current_data['d']
457-
else:
458-
for query in queries:
459-
if current_data['d'][query] == queries[query]:
460-
yield current_data['d']
461-
else:
462-
break
449+
if line != "\n": # empty lines fail on json.loads()
450+
current_data = json.loads(line)
451+
# If we are not searching for anything
452+
if not queries:
453+
if show_row:
454+
current_data['d']["_row"] = current_data['r']
455+
yield current_data['d']
456+
else:
457+
for query in queries:
458+
if current_data['d'][query] == queries[query]:
459+
yield current_data['d']
460+
else:
461+
break
463462

464463
def vacuum(self) -> bool:
465464
"""
@@ -545,14 +544,12 @@ def __check_write_success(self, data, page: str, method: str) -> bool:
545544
"""
546545
Checks to make sure the previous update or delete was successful.
547546
"""
548-
# Initiate line-counter
549-
current_line = 1
550547
# Calculate what line will have the row we are looking for.
551548
looking_for_line = self.__row_id_in_file(list(data)[0])
552549
row_id = list(data)[0]
553550
# open file at path
554551
with open(page, 'r') as f:
555-
for line in f:
552+
for current_line, line in enumerate(f):
556553
if current_line == looking_for_line:
557554
if method == "update":
558555
json_line = json.loads(line)
@@ -562,7 +559,6 @@ def __check_write_success(self, data, page: str, method: str) -> bool:
562559
elif method == "delete":
563560
if line == "\n":
564561
return True
565-
current_line += 1
566562
# There was a problem writing, so return false
567563
return False
568564

@@ -712,67 +708,40 @@ def __modify_data_file(self, path: str, update_data, action: str) -> bool:
712708
"does not exist".format(action))
713709

714710
temp_path = "{}.temp".format(path)
715-
wrote_to_file = False
716711
current_data = ''
717-
current_line = 1
718-
file_row_offset = ''
719-
# Calculate the row offset for current data page file
720-
for number in path.split('/')[-1][4:]:
721-
if number in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
722-
file_row_offset = "{}{}".format(file_row_offset, number)
723-
else:
724-
break
725-
file_row_offset = int(file_row_offset) - 1
712+
row_id = next(iter(update_data))
726713
# Open the master data page file
727714
with open(path, 'r') as input_file:
728715
# Create a temporary data page file
729716
with open(temp_path, 'w') as output:
730-
for line in input_file:
731-
current_row_id = current_line + file_row_offset
732-
# If we are at the row we need to modify
733-
if current_row_id in update_data:
734-
# If we are deleting a row:
735-
if action == 'delete':
736-
output.write('\n')
737-
wrote_to_file = True
738-
# If we are updating a row:
739-
else:
740-
current_data = json.loads(line)
741-
if current_data['r'] == current_row_id:
742-
# Find a match for the column name the user
743-
# wants to update with new data.
744-
for x in current_data['d']:
745-
for y in update_data[current_row_id]:
746-
# If the column the user specified
747-
# equals the column in the current data
748-
if y == x:
749-
# Then update the data with new
750-
# user input
751-
current_data['d'][x] = update_data[
752-
current_row_id][y]
753-
# and write to temp file
754-
output.write(json.dumps(current_data))
755-
output.write('\n')
756-
wrote_to_file = True
717+
for line_num, line in enumerate(input_file):
718+
if line != "\n":
719+
current_data = json.loads(line)
720+
# If this is our line
721+
if current_data["r"] == row_id:
722+
# Write the modified line to the file
723+
if action == 'delete':
724+
# output.write('\n')
725+
pass
726+
# If we are updating a row:
757727
else:
758-
raise Exception("Woah we thought {} was row_id"
759-
" {} and almost stomped the "
760-
"wrong row's data!".format(
761-
line, current_row_id))
762-
# Else we are not at the row we are updating, so just copy
763-
# the previous data to the temp file.
764-
else:
765-
output.write(line)
766-
current_line += 1
767-
# If we performed an update, check to make sure we actually wrote
768-
# the update to the temp file
769-
if wrote_to_file:
770-
if self.__check_write_success(update_data, temp_path, action):
771-
os.remove(path)
772-
os.rename(temp_path, path)
773-
return True
774-
else:
775-
return False
728+
if current_data['r'] == row_id:
729+
current_data['d'].update(update_data[row_id])
730+
output.write(json.dumps(current_data))
731+
output.write('\n')
732+
else:
733+
raise Exception("Woah we thought {} was row_id"
734+
" {} and almost stomped the "
735+
"wrong row's data!".format(
736+
line, line_num))
737+
# Otherwise, write the line to the file as-is, skipping empty lines
738+
else:
739+
output.write(line)
740+
# imposible to check as we have ommited empty lines
741+
os.remove(path)
742+
os.rename(temp_path, path)
743+
return True
744+
776745

777746
def __data_file_for_row_id(self, row_id: int) -> str:
778747
"""
@@ -799,10 +768,12 @@ def __row_id_in_file(self, row_id: int) -> int:
799768
if row_id == 0:
800769
return 0
801770
else:
802-
file_row_id = int(row_id) % int(self.rows_per_page)
803-
if file_row_id == 0:
804-
file_row_id = int(file_row_id) + int(self.rows_per_page)
805-
return file_row_id
771+
with open(self.__data_file_for_row_id(row_id), 'r') as f:
772+
for line_num, line in enumerate(f):
773+
if line != "\n":
774+
if json.loads(line)["r"] == row_id:
775+
return line_num
776+
return False
806777

807778
def __scrub_data(self, data: any, fill_missing: bool = True):
808779
"""
@@ -819,12 +790,10 @@ def __scrub_data(self, data: any, fill_missing: bool = True):
819790
# if received list of values - make a dict with fields
820791
if(isinstance(data, list)):
821792
ndata = {}
822-
print(self.columns, data)
823793
for k, v in zip(self.columns, data):
824794
ndata[k]=v
825795
data = ndata
826796
del(ndata)
827-
print(type(data), data)
828797
try:
829798
for column, value in data.items():
830799
column = column.lower()

0 commit comments

Comments
 (0)