Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
3 """Script to extract the database schema from SQLite database files. | 3 """Script to extract the database schema from SQLite database files. |
4 | 4 |
5 The resulting schema will be placed into your clipboard which can then | 5 The resulting schema will be placed into your clipboard which can then |
6 be pasted directly into your plugin. | 6 be pasted directly into your plugin. |
7 | 7 |
8 This script requires the pyperclip Python module. | 8 This script requires the pyperclip Python module. |
9 """ | 9 """ |
10 | 10 |
11 from __future__ import print_function | 11 from __future__ import print_function |
12 import argparse | 12 import argparse |
13 import os | 13 import os |
14 import sys | 14 import sys |
15 import textwrap | 15 import textwrap |
16 | 16 |
17 #import pyperclip # pylint: disable=import-error | 17 import pyperclip # pylint: disable=import-error |
18 | 18 |
19 # Change PYTHONPATH to include plaso. | 19 # Change PYTHONPATH to include plaso. |
20 sys.path.insert(0, u'.') | 20 sys.path.insert(0, u'.') |
21 | 21 |
22 from plaso.parsers import sqlite # pylint: disable=wrong-import-position | 22 from plaso.parsers import sqlite # pylint: disable=wrong-import-position |
23 | 23 |
24 | 24 |
25 class SQLiteSchemaExtractor(object): | 25 class SQLiteSchemaExtractor(object): |
26 """SQLite database file schema extractor.""" | 26 """SQLite database file schema extractor.""" |
27 | 27 |
28 def GetDatabaseSchema(self, database_path, wal_path=None): | 28 def GetDatabaseSchema(self, database_path, wal_path=None): |
29 """Retrieves schema from given database. | 29 """Retrieves schema from given database. |
30 | 30 |
31 Args: | 31 Args: |
32 database_path (str): file path to database. | 32 database_path (str): file path to database. |
33 wal_path (Optional[str]): file path to wal file. | 33 wal_path (Optional[str]): file path to WAL file. |
34 | 34 |
35 Returns: | 35 Returns: |
36 dict[str, str]: schema as an SQL query per table name. | 36 dict[str, str]: schema as an SQL query per table name. |
37 """ | 37 """ |
38 database = sqlite.SQLiteDatabase('database.db') | 38 database = sqlite.SQLiteDatabase('database.db') |
39 | 39 |
40 with open(database_path, u'rb') as file_object: | 40 with open(database_path, u'rb') as file_object: |
41 wal_file_object = None | 41 wal_file_object = None |
42 if wal_path: | 42 if wal_path: |
43 wal_file_object = open(wal_path, u'rb') | 43 wal_file_object = open(wal_path, u'rb') |
(...skipping 20 matching lines...) Expand all Loading... | |
64 str: schema formated as word-wrapped string. | 64 str: schema formated as word-wrapped string. |
65 """ | 65 """ |
66 textwrapper = textwrap.TextWrapper() | 66 textwrapper = textwrap.TextWrapper() |
67 textwrapper.break_long_words = False | 67 textwrapper.break_long_words = False |
68 textwrapper.drop_whitespace = True | 68 textwrapper.drop_whitespace = True |
69 textwrapper.width = 80 - (10 + 4) | 69 textwrapper.width = 80 - (10 + 4) |
70 | 70 |
71 lines = [] | 71 lines = [] |
72 table_index = 1 | 72 table_index = 1 |
73 number_of_tables = len(schema) | 73 number_of_tables = len(schema) |
74 for table_name, query in schema.items(): | 74 for table_name, query in schema.items(): |
dc3.plaso
2017/05/09 18:52:44
The original Jinja2 template was using dictsort to
Joachim Metz
2017/05/28 12:02:46
Acknowledged.
| |
75 line = u' u\'{0:s}\': ('.format(table_name) | 75 line = u' u\'{0:s}\': ('.format(table_name) |
76 lines.append(line) | 76 lines.append(line) |
77 | 77 |
78 query = query.replace(u'\'', u'\\\'') | 78 query = query.replace(u'\'', u'\\\'') |
79 query = textwrapper.wrap(query) | 79 query = textwrapper.wrap(query) |
80 query = [u'{0:s}u\'{1:s} \''.format(u' ' * 10, line) for line in query] | 80 query = [u'{0:s}u\'{1:s} \''.format(u' ' * 10, line) for line in query] |
81 | 81 |
82 if table_index == number_of_tables: | 82 if table_index == number_of_tables: |
83 query[-1] = u'{0:s}\')}}]'.format(query[-1][:-2]) | 83 query[-1] = u'{0:s}\')}}]'.format(query[-1][:-2]) |
84 else: | 84 else: |
85 query[-1] = u'{0:s}\'),'.format(query[-1][:-2]) | 85 query[-1] = u'{0:s}\'),'.format(query[-1][:-2]) |
86 | 86 |
87 lines.extend(query) | 87 lines.extend(query) |
88 table_index += 1 | 88 table_index += 1 |
89 | 89 |
90 return u'\n'.join(lines) | 90 return u'\n'.join(lines) |
91 | 91 |
92 | 92 |
93 if __name__ == u'__main__': | 93 if __name__ == u'__main__': |
94 argument_parser = argparse.ArgumentParser() | 94 argument_parser = argparse.ArgumentParser() |
95 | 95 |
96 argument_parser.add_argument( | 96 argument_parser.add_argument( |
97 u'database_path', type=str, | 97 u'database_path', type=str, |
98 help=u'The path to the database file to extract schema from.') | 98 help=u'The path to the database file to extract schema from.') |
99 | 99 |
100 argument_parser.add_argument( | 100 argument_parser.add_argument( |
101 u'wal_path', type=str, nargs=u'?', default=None, | 101 u'wal_path', type=str, nargs=u'?', default=None, |
102 help=u'Optional path to a wal file to commit into the database.') | 102 help=u'Optional path to a WAL file to commit into the database.') |
103 | 103 |
104 options = argument_parser.parse_args() | 104 options = argument_parser.parse_args() |
105 | 105 |
106 if not os.path.exists(options.database_path): | 106 if not os.path.exists(options.database_path): |
107 print(u'No such database file: {0:s}'.format(options.database_path)) | 107 print(u'No such database file: {0:s}'.format(options.database_path)) |
108 sys.exit(1) | 108 sys.exit(1) |
109 | 109 |
110 if options.wal_path and not os.path.exists(options.wal_path): | 110 if options.wal_path and not os.path.exists(options.wal_path): |
111 print(u'No such wal file: {0:s}'.format(options.wal_path)) | 111 print(u'No such WAL file: {0:s}'.format(options.wal_path)) |
112 sys.exit(1) | 112 sys.exit(1) |
113 | 113 |
114 extractor = SQLiteSchemaExtractor() | 114 extractor = SQLiteSchemaExtractor() |
115 | 115 |
116 database_schema = extractor.GetDatabaseSchema( | 116 database_schema = extractor.GetDatabaseSchema( |
117 options.database_path, options.wal_path) | 117 options.database_path, options.wal_path) |
118 | 118 |
119 database_schema = extractor.FormatSchema(database_schema) | 119 database_schema = extractor.FormatSchema(database_schema) |
120 | 120 |
121 #pyperclip.copy(database_schema) | 121 pyperclip.copy(database_schema) |
Joachim Metz
2017/04/20 05:36:25
fix this in final touch up
Joachim Metz
2017/05/07 14:27:10
Done.
| |
122 print(database_schema) | |
123 | 122 |
124 sys.exit(0) | 123 sys.exit(0) |
LEFT | RIGHT |