コード例 #1
0
ファイル: facade.py プロジェクト: woodfrog/minisql
 def insert_record(table_name, attributes):
     RecordManager.set_file_dir('schema/tables/' + table_name + '/')
     metadata = load_metadata()
     position = RecordManager.insert(table_name,
                                     metadata.tables[table_name].fmt,
                                     tuple(attributes))
     for index_name, index in metadata.tables[table_name].indexes.items():
         file_path = RecordManager.file_dir + index_name + '.index'
         fmt = ''.join(metadata.tables[table_name].columns[column].fmt
                       for column in index.columns)
         manager = IndexManager(file_path, fmt)
         key_pos = list(metadata.tables[table_name].columns.keys()).index(
             index.columns[0])
         key_list = list()
         key_list.append(attributes[key_pos])
         try:
             manager.insert(
                 key_list, position)  # index can be set on single attribute
             manager.dump_header()
         except ValueError:  # duplicated key, the inserted record should be deleted
             RecordManager.delete(table_name,
                                  metadata.tables[table_name].fmt,
                                  with_index=True,
                                  record_offset=position)
             raise
コード例 #2
0
ファイル: facade.py プロジェクト: woodfrog/minisql
 def select_record_all(table_name):
     metadata = load_metadata()
     RecordManager.set_file_dir('schema/tables/' + table_name + '/')
     records = RecordManager.select(table_name,
                                    metadata.tables[table_name].fmt,
                                    with_index=False,
                                    conditions={})
     return records
コード例 #3
0
ファイル: facade.py プロジェクト: woodfrog/minisql
    def _select_single_condition(table_name, condition):
        metadata = load_metadata()
        index_name = MinisqlFacade._has_index(condition[0], table_name)
        if index_name:
            print('select with index on ', condition[0])
            attribute_name = condition[0]
            operator = condition[1]
            key_list = list()
            key_list.append(condition[2])
            file_path = RecordManager.file_dir + index_name + '.index'  #
            fmt = metadata.tables[table_name].columns[attribute_name].fmt
            manager = IndexManager(file_path, fmt)
            records = list()
            if operator == '=':
                try:
                    itr = manager.find(key_list)
                    it_key, value = next(itr)
                    if it_key[0] == key_list[0]:
                        records.append(
                            RecordManager.select(
                                table_name,
                                metadata.tables[table_name].fmt,
                                with_index=True,
                                record_offset=value))
                except StopIteration:
                    pass
            elif operator == '>':
                for i in manager.find(key_list):
                    if i[0][0] > key_list[0]:
                        value = i[1]
                        records.append(
                            RecordManager.select(
                                table_name,
                                metadata.tables[table_name].fmt,
                                with_index=True,
                                record_offset=value))
            elif operator == '<':
                for i in manager.iter_leaves():
                    if i[0][0] < key_list[0]:
                        value = i[1]
                        records.append(
                            RecordManager.select(
                                table_name,
                                metadata.tables[table_name].fmt,
                                with_index=True,
                                record_offset=value))
                    else:
                        break
            else:
                pass
        else:
            records = MinisqlFacade.select_record_conditionally_without_index(
                table_name, condition)

        return records
コード例 #4
0
ファイル: facade.py プロジェクト: woodfrog/minisql
 def delete_record_conditionally_without_index(table_name, condition):
     metadata = load_metadata()
     condition_convert = MinisqlFacade._convert_conditions(
         table_name, condition)
     records = RecordManager.select(table_name,
                                    metadata.tables[table_name].fmt,
                                    with_index=False,
                                    conditions=condition_convert)
     for record in records:
         MinisqlFacade._delete_stupid_index(record, table_name)
     RecordManager.delete(table_name,
                          metadata.tables[table_name].fmt,
                          with_index=False,
                          conditions=condition_convert)
コード例 #5
0
ファイル: facade.py プロジェクト: woodfrog/minisql
    def delete_record_conditionally(table_name, conditions):
        RecordManager.set_file_dir('schema/tables/' + table_name + '/')
        metadata = load_metadata()
        if len(conditions) == 1:
            MinisqlFacade._delete_single_condition(table_name, conditions[0])
        elif len(conditions) == 3:
            if conditions[1] == 'and':
                records = MinisqlFacade.select_record_conditionally(
                    table_name, conditions)
                for record in records:
                    for index_name, index in metadata.tables[
                            table_name].indexes.items():
                        file_path = RecordManager.file_dir + index_name + '.index'
                        fmt = ''.join(
                            metadata.tables[table_name].columns[column].fmt
                            for column in index.columns)
                        manager = IndexManager(file_path, fmt)
                        pos = list(
                            metadata.tables[table_name].columns.keys()).index(
                                index.columns[0])
                        key_list = list()
                        key_list.append(record[pos])
                        itr = manager.find(key_list)
                        trash, value = next(itr)
                        manager.delete(key_list)
                        manager.dump_header()
                    RecordManager.delete(table_name,
                                         metadata.tables[table_name].fmt,
                                         with_index=1,
                                         record_offset=value)

            # each tuple has its PRIMARY KEY index
            # actually only support single attribute index
            elif conditions[1] == 'or':
                MinisqlFacade._delete_single_condition(table_name,
                                                       conditions[0])
                MinisqlFacade._delete_single_condition(table_name,
                                                       conditions[2])
            else:
                pass
                # link the records outside
        else:
            pass
コード例 #6
0
ファイル: facade.py プロジェクト: woodfrog/minisql
 def select_record_conditionally_without_index(
         table_name, condition):  # support only equivalent search
     metadata = load_metadata()
     condition_convert = MinisqlFacade._convert_conditions(
         table_name, condition)
     records = RecordManager.select(table_name,
                                    metadata.tables[table_name].fmt,
                                    with_index=False,
                                    conditions=condition_convert)
     return records
コード例 #7
0
ファイル: facade.py プロジェクト: woodfrog/minisql
 def delete_record_all(table_name):
     RecordManager.set_file_dir('schema/tables/' + table_name + '/')
     metadata = load_metadata()
     RecordManager.delete(table_name,
                          metadata.tables[table_name].fmt,
                          with_index=False,
                          conditions={})
     for index_name, index in metadata.tables[table_name].indexes.items():
         file_path = RecordManager.file_dir + index_name + '.index'
         fmt = ''.join(metadata.tables[table_name].columns[column].fmt
                       for column in index.columns)
         manager = IndexManager(file_path, fmt)
         try:
             for i in manager.iter_leaves():
                 key_list = list()
                 key_list.append(i[0][0])
                 manager.delete(key_list)
         except RuntimeError:
             pass
コード例 #8
0
ファイル: facade.py プロジェクト: woodfrog/minisql
 def create_table(table_name, primary_key, columns):
     os.makedirs('schema/tables/' + table_name, exist_ok=True)
     metadata = load_metadata()  # PK can be set on only one attribute
     columns_lst = []
     for column in columns:
         # generate the fmt for this column
         if column[1][0] == 'char':
             fmt = str(column[1][1]) + 's'
         elif column[1][0] == 'int':
             fmt = str(column[1][1]) + 'i'
         else:
             fmt = str(column[1][1]) + 'd'
         columns_lst.append(
             Column(column[0],
                    fmt,
                    primary_key=(column[0] == primary_key),
                    unique=column[2]))
     metadata.add_table(table_name, *columns_lst)
     RecordManager.set_file_dir('schema/tables/' + table_name + '/')
     RecordManager.init_table(table_name)
     metadata.dump()
コード例 #9
0
ファイル: facade.py プロジェクト: woodfrog/minisql
    def select_record_conditionally(table_name, conditions):
        RecordManager.set_file_dir('schema/tables/' + table_name + '/')
        records = list()
        if len(conditions) == 1:
            records += (MinisqlFacade._select_single_condition(
                table_name, conditions[0]))
        elif len(conditions) == 3:
            record_1 = MinisqlFacade._select_single_condition(
                table_name, conditions[0])
            record_2 = MinisqlFacade._select_single_condition(
                table_name, conditions[2])
            if conditions[1] == 'and':
                records = list(set(record_1).intersection(set(record_2)))
            elif conditions[1] == 'or':
                records = list(set(record_1).union(set(record_2)))
            else:
                pass
                # link the records outside
        else:
            pass

        return records
コード例 #10
0
ファイル: facade.py プロジェクト: woodfrog/minisql
 def create_index(table_name, index_name, column_name):
     RecordManager.set_file_dir('schema/tables/' + table_name + '/')
     offset = -1
     metadata = load_metadata()
     metadata.add_index(table_name, index_name, column_name)
     records = RecordManager.select(table_name,
                                    metadata.tables[table_name].fmt,
                                    with_index=False,
                                    conditions={})
     file_path = RecordManager.file_dir + index_name + '.index'
     table_target = metadata.tables[table_name]
     fmt = ''.join(table_target.columns[column].fmt
                   for column in table_target.indexes[index_name].columns)
     manager = IndexManager(file_path, fmt)
     key_pos = list(
         metadata.tables[table_name].columns.keys()).index(column_name)
     for record in records:
         key_list = list()
         key_list.append(record[key_pos])
         offset += 1
         manager.insert(key_list, offset)
     metadata.dump()
     manager.dump_header()
コード例 #11
0
 def setUp(self):
     RecordManager.init_table('gg')
     RecordManager.init_table('ggg')
     RecordManager.init_table('foo3')
コード例 #12
0
 def setUp(self):
     RecordManager.init_table('foo')
     RecordManager.init_table('foo2')
コード例 #13
0
 def test_without_index(self):
     RecordManager.insert('foo3', 'i4sd', (1, 'abcd', 1.0))
     RecordManager.insert('foo3', 'i4sd', (1, 'bcde', 1.0))
     conditions = dict()
     conditions[0] = {'=': 1}
     self.assertEqual(
         RecordManager.select('foo3',
                              'i4sd',
                              with_index=False,
                              conditions=conditions), [(1, 'abcd', 1.0),
                                                       (1, 'bcde', 1.0)])
     RecordManager.delete('foo3',
                          'i4sd',
                          with_index=False,
                          conditions=conditions)
     self.assertEqual(
         RecordManager.select('foo3',
                              'i4sd',
                              with_index=False,
                              conditions=conditions), [])
     RecordManager.insert('foo3', 'i4sd', (1, 'abcd', 1.0))
     RecordManager.insert('foo3', 'i4sd', (1, 'bcde', 1.0))
     del conditions[0]
     conditions[1] = {'=': 'abcd'}
     RecordManager.update('foo3',
                          'i4sd', (2, 'cccc', 1.0),
                          with_index=False,
                          conditions=conditions)
     del conditions[1]
     conditions[2] = {'=': 1.0}
     self.assertEqual(
         RecordManager.select('foo3',
                              'i4sd',
                              with_index=False,
                              conditions=conditions), [(1, 'bcde', 1.0),
                                                       (2, 'cccc', 1.0)])
コード例 #14
0
 def test_repeat_file(self):
     with self.assertRaises(RuntimeError):
         RecordManager.init_table('foo3')
     with self.assertRaises(RuntimeError):
         RecordManager.init_table('gg')
コード例 #15
0
 def test_records_with_string(self):
     RecordManager.insert('ggg', '<idi4s', (1, 2.0, 3, 'temps'))
     # todo: check the length of string in the given attributes ?
     self.assertEqual(
         RecordManager.select('ggg',
                              '<idi4s',
                              with_index=True,
                              record_offset=0), (1, 2.0, 3, 'temp'))
     RecordManager.insert('ggg', '<idi4s',
                          (1, 2.0, 3, 'no'))  # less than maximum length
     self.assertEqual(
         RecordManager.select('ggg',
                              '<idi4s',
                              with_index=True,
                              record_offset=1), (1, 2.0, 3, 'no'))
     RecordManager.update('ggg',
                          '<idi4s', (1, 2.0, 3, 'nono'),
                          with_index=True,
                          record_offset=1)
     self.assertEqual(
         RecordManager.select('ggg',
                              '<idi4s',
                              with_index=True,
                              record_offset=1), (1, 2.0, 3, 'nono'))
     RecordManager.delete('ggg', '<idi4s', with_index=True, record_offset=1)
     RecordManager.delete('ggg', '<idi4s', with_index=True, record_offset=0)
     with self.assertRaises(RuntimeError):
         RecordManager.select('ggg',
                              '<idi4s',
                              with_index=True,
                              record_offset=0)
         RecordManager.update('ggg',
                              '<idi4s', (1, 2.0, 3, 'nono'),
                              with_index=True,
                              record_offset=1)
コード例 #16
0
 def test_record_manager(self):
     RecordManager.insert('gg', '<idi', (1, 3.0, 4))
     RecordManager.insert('gg', '<idi', (-1, 3.5, -1))
     self.assertEqual(
         RecordManager.select('gg',
                              '<idi',
                              with_index=True,
                              record_offset=1), (-1, 3.5, -1))
     RecordManager.update('gg',
                          '<idi', (1, 3.0, 4),
                          with_index=True,
                          record_offset=1)
     self.assertEqual(
         RecordManager.select('gg',
                              '<idi',
                              with_index=True,
                              record_offset=1), (1, 3.0, 4))
     RecordManager.delete('gg', '<idi', with_index=True, record_offset=1)
     with self.assertRaises(RuntimeError):
         RecordManager.select('gg',
                              '<idi',
                              with_index=True,
                              record_offset=1)
         RecordManager.update('gg',
                              '<idi', (1, 2.0, 3),
                              with_index=True,
                              record_offset=1)