Making REPL

We will try to maintain the structure of the REPL of the code in C wherever we can. So we can Start by creating a main function. This main function will have a while Loop that runs until we manually exit or kill the terminal.

def main():
    while True:
        print_prompt()
        user_input = read_input()

        if user_input.startswith('.'):
            result = do_meta_command(user_input)
            if result == MetaCommandResult.SUCCESS:
                continue
            elif result == MetaCommandResult.UNRECOGNIZED_COMMAND:
                print(f"Unrecognized command '{user_input}'")
                continue

        # 2. Prepare Statement
        statement = Statement()
        result = prepare_statement(user_input, statement)
        
        if result == PrepareResult.UNRECOGNIZED_STATEMENT:
            print(f"Unrecognized keyword at start of '{user_input}'.")
            continue
        
        # 3. Execute Statement
        execute_statement(statement)
        print("Executed.")
        

The Loop starts out by printing db >. We then take in the input and split it into a meta command or a statement.

The print statement function is very straightforward.

def print_prompt():
    print("db > ", end="", flush=True)

Now for reading the input if we get an error while reading or we recieve None, we immediately exit the DB

def read_input():
    try:
        return input().strip()
    except EOFError:
        print()
        return ".exit"
    except Exception as e:
        print(f"Error reading input: {e}")
        sys.exit(1)

Currently we need a way to maintain what is the status of the command executed. Later on we can use simple string in C we would use struct Enum, we will try to simulate that here

class MetaCommandResult(Enum):
    SUCCESS = 1
    UNRECOGNIZED_COMMAND = 2

class PrepareResult(Enum):
    SUCCESS = 1
    UNRECOGNIZED_STATEMENT = 2

class StatementType(Enum):
    INSERT = 1
    SELECT = 2

class Statement:
    def __init__(self):
        self.type = None

Now for the meta-command we start by adding a single exit command.

def do_meta_command(user_input):
    if user_input == ".exit":
        sys.exit(0)
    else:
        return MetaCommandResult.UNRECOGNIZED_COMMAND

Now for the statement like insert and select we first need to first prepare it. This function just sets the type of statement it is.

def prepare_statement(user_input, statement):
    if user_input.startswith("insert"):
        statement.type = StatementType.INSERT
        return PrepareResult.SUCCESS
    if user_input == "select":
        statement.type = StatementType.SELECT
        return PrepareResult.SUCCESS
    
    return PrepareResult.UNRECOGNIZED_STATEMENT

Finally we need to execute the statement.

def execute_statement(statement):
    if statement.type == StatementType.INSERT:
        print("This is where we would do an insert.")
    elif statement.type == StatementType.SELECT:
        print("This is where we would do a select.")

Basic Table