blob: 4637e8dee01852180cd783a7b521f2fdb67ec91d [file] [log] [blame]
#!/usr/bin/python
# Copyright 2018 The Tulsi Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Manages our dSYM SQLite database schema."""
import errno
import os
import sqlite3
SQLITE_SYMBOL_CACHE_PATH = os.path.expanduser('~/Library/Application Support/'
'Tulsi/Scripts/symbol_cache.db')
class SymbolCacheSchema(object):
"""Defines and updates the SQLite database used for DBGShellCommands."""
current_version = 1
def UpdateSchemaV1(self, connection):
"""Updates the database to the v1 schema.
Args:
connection: Connection to the database that needs to be updated.
Returns:
True if the database reported that it was updated to v1.
False if not.
"""
# Create the table (schema version 1).
cursor = connection.cursor()
cursor.execute('CREATE TABLE symbol_cache('
'uuid TEXT PRIMARY KEY, '
'dsym_path TEXT, '
'architecture TEXT'
');')
# NOTE: symbol_cache (uuid) already has an index, as the PRIMARY KEY.
# Create a unique index to keep dSYM paths and architectures unique.
cursor.execute('CREATE UNIQUE INDEX idx_dsym_arch '
'ON '
'symbol_cache('
'dsym_path, '
'architecture'
');')
cursor.execute('PRAGMA user_version = 1;')
# Verify the updated user_version, as confirmation of the update.
cursor.execute('PRAGMA user_version;')
return cursor.fetchone()[0] == 1
def VerifySchema(self, connection):
"""Updates the database to the latest schema.
Args:
connection: Connection to the database that needs to be updated.
Returns:
True if the database reported that it was updated to the latest schema.
False if not.
"""
cursor = connection.cursor()
cursor.execute('PRAGMA user_version;') # Default is 0
db_version = cursor.fetchone()[0]
# Update to the latest schema in the given database, if necessary.
if db_version < self.current_version:
# Future schema updates will build on this.
if self.UpdateSchemaV1(connection):
db_version = 1
# Return if the database has been updated to the latest schema.
return db_version == self.current_version
def InitDB(self, db_path):
"""Initializes a new connection to a SQLite database.
Args:
db_path: String representing a reference to the SQLite database.
Returns:
A sqlite3.connection object representing an active connection to
the database referenced by db_path.
"""
# If this is not an in-memory SQLite database...
if ':memory:' not in db_path:
# Create all subdirs before we create a new db or connect to existing.
if not os.path.isfile(db_path):
try:
os.makedirs(os.path.dirname(db_path))
except OSError as e:
if e.errno != errno.EEXIST:
raise
connection = sqlite3.connect(db_path)
# Update to the latest schema and return the db connection.
if self.VerifySchema(connection):
return connection
else:
return None
def __init__(self, db_path=SQLITE_SYMBOL_CACHE_PATH):
self.connection = self.InitDB(db_path)
def __del__(self):
if self.connection:
self.connection.close()