-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommandParser.py
More file actions
203 lines (166 loc) · 7.17 KB
/
Copy pathcommandParser.py
File metadata and controls
203 lines (166 loc) · 7.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
class CommandParser:
def __init__(self, data):
# Dynamically create the table dictionary
self.tables = {key: value for key, value in data.items()}
self.commands = {
"SELECT": self.handle_select,
"PROJECT": self.handle_project,
"JOIN": self.handle_join,
"INTERSECT": self.handle_intersection,
"UNION": self.handle_union,
"MINUS": self.handle_minus
}
def parse(self, command):
# Convert command to upper case
tokens = command.split()
command_type = tokens[0].upper()
if command_type == "SELECT":
if "FROM" in tokens:
from_index = tokens.index("FROM")
columns = tokens[1:from_index]
table = tokens[from_index + 1]
table = table.lower()
self.commands[command_type](columns, table)
else:
print("Syntax error while using select")
if command_type == "PROJECT":
if "FROM" in tokens:
from_index = tokens.index("FROM")
columns = tokens[1:from_index]
table = tokens[from_index + 1]
table = table.lower()
self.commands[command_type](columns, table)
else:
print("Syntax error while using project")
if command_type == "JOIN":
if len(tokens) == 3:
table1 = tokens[1].lower()
table2 = tokens[2].lower()
if table1 in self.tables and table2 in self.tables:
result = self.commands[command_type](table1, table2)
print(result)
else:
print("Error: one or both tables do not exist")
else:
print("Syntax error while joining")
if command_type == "INTERSECT":
if len(tokens) == 3:
table1 = tokens[1].lower()
table2 = tokens[2].lower()
if table1 in self.tables and table2 in self.tables:
result = self.commands[command_type](table1, table2)
print(result)
else:
print("Error: one or both tables do not exist")
else:
print("Syntax error while intersection")
if command_type == "UNION":
if len(tokens) == 3:
table1 = tokens[1].lower()
table2 = tokens[2].lower()
if table1 in self.tables and table2 in self.tables:
result = self.commands[command_type](table1, table2)
print(result)
else:
print("Error: one or both tables do not exist")
else:
print("Syntax error during union operation")
if command_type == "MINUS":
if len(tokens) == 3:
table1 = tokens[1].lower()
table2 = tokens[2].lower()
if table1 in self.tables and table2 in self.tables:
result = self.commands[command_type](table1, table2)
print(result)
else:
print("Error: one or both tables do not exist")
else:
print("Syntax error during minus operation")
@staticmethod
def selection(table, columns):
"""Select rows where column equals value"""
return [{col: row.get(col, None) for col in columns} for row in table]
def handle_select(self, columns, table):
if table in self.tables:
if all(col in self.tables[table][0].keys() for col in columns):
result = self.selection(self.tables[table], columns)
print(result)
else:
print("invalid columns")
else:
print(f"No such table: {table}")
@staticmethod
def projection(table, columns):
"""Select specific columns from the table"""
seen = set()
result = []
for row in table:
# Create a tuple with the values of the specified columns
projected_row = tuple(row[col] for col in columns if col in row)
# Check if this tuple is unique (not in seen set)
if projected_row not in seen:
seen.add(projected_row) # Mark this tuple as seen
# Convert the tuple back to a dictionary and add it to the result
result.append({col: row[col] for col in columns if col in row})
return result
def handle_project(self, columns, table):
if table in self.tables:
if all(col in self.tables[table][0].keys() for col in columns):
result = self.projection(self.tables[table], columns)
print(result)
else:
print("invalid columns")
else:
print(f"No such table: {table}")
@staticmethod
def inner_join(table1, table2, join_column):
"""Perform an inner join between two tables on a specified column."""
# Creating a dictionary for the second table keyed by the join column
table2_dict = {row[join_column]: row for row in table2 if join_column in row}
# Iterating over table1 and assembling the joined rows
joined_table = []
for row1 in table1:
key = row1.get(join_column)
if key in table2_dict:
# Combine rows from both tables if the join column value matches
joined_row = {**row1, **table2_dict[key]}
joined_table.append(joined_row)
return joined_table
def handle_join(self, table1, table2):
table1 = self.tables[table1]
table2 = self.tables[table2]
# Find a common column for joining
common_columns = set(table1[0].keys()).intersection(table2[0].keys())
if not common_columns:
return "Error: No common columns found for JOIN operation"
join_column = common_columns.pop() # Using the first common column found
return self.inner_join(table1, table2, join_column)
def handle_intersection(self, table1, table2):
table1 = self.tables[table1]
table2 = self.tables[table2]
# Intersection logic: Find common rows in both tables
intersection = []
for row1 in table1:
for row2 in table2:
if row1 == row2:
intersection.append(row1)
return intersection
def handle_union(self, table1, table2):
table1 = self.tables[table1]
table2 = self.tables[table2]
# Union logic: Combine rows from tables and remove duplicates
union = table1.copy()
for row in table2:
if row not in union:
union.append(row)
return union
def handle_minus(self, table1, table2):
table1 = self.tables[table1]
table2 = self.tables[table2]
# Minus logic: Find rows in table1 that are not in table 2
difference = [row for row in table1 if row not in table2]
return difference
# Example Usage
# parser.parse("SELECT column1 column2 FROM table")
# parser.parse("PROJECT column3 FROM table")
# parser.parse("JOIN table1 table2")