database_operations.py 文件源码

python
阅读 23 收藏 0 点赞 0 评论 0

项目:united-states-of-browsers 作者: kchawla-pi 项目源码 文件源码
def yield_source_records(source_db_paths: Dict[Text, PathInfo],
                         source_fieldnames: Sequence[Text]
                         ) -> Generator[NamedTuple, None, None]:
    """ Returns a generator of named tuple which can yield a record across all database files.
    Accepts dict of profile names and their database filepaths; and inclusive list of fieldnames.

    source_db_paths: {Profile names: profile database filepaths}
    source_fieldnames: list of fieldnames inclusive of all the fieldnames across all database files.

    returns: Generator of namedtuple which can yield each record.
    """
    global DBRecord
    # Additional field to store last_visited_date field value converted from microsceonds to human usable format.
    # source_fieldnames.append('visited_on')  # will likely be moved to browser specific settings, when otjer browsers are added.
    DBRecord = namedtuple('DBRecord', source_fieldnames)
    incr = helpers.incrementer()
    source_records_template = odict.fromkeys(source_fieldnames, None)
    for profile_name, profile_db_path in source_db_paths.items():
        with sqlite3.connect(profile_db_path) as source_conn:
            source_conn.row_factory = sqlite3.Row
            try:
                for db_record_yielder in source_conn.execute("""SELECT * FROM moz_places WHERE title IS NOT NULL"""):
                    ''' Prevents adding additional keys, only updates keys/fields specified in source_fieldnames.
                    Prevents field mismatches among profiles, ex: favicon_url in Firefox exists in some profiles not in others.
                    '''
                    source_records_template = odict(
                                (key, dict(db_record_yielder).setdefault(key, None))
                                    for key in source_records_template)
                    # Couldn't figure out how to make AUTOINCREMENT PRIMARY KEY work in SQL, hence this serial# generator.
                    source_records_template['id'] = next(incr)
                    try:
                        source_records_template['last_visit_date_readable'] = dt.fromtimestamp(source_records_template['last_visit_date'] // 10**6).strftime('%x %X')
                    except TypeError:
                        pass
                    # OrderedDict converted to NamedTuple as tuples easily convert to SQL query bindings.
                    yield DBRecord(*source_records_template.values())
            except sqlite3.OperationalError:
                print(f'This browser profile does not seem to have any data: {profile_name}')
评论列表
文章目录


问题


面经


文章

微信
公众号

扫码关注公众号