Coverage for src/robotide/spec/librarydatabase.py: 81%
83 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-06 10:40 +0100
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-06 10:40 +0100
1# Copyright 2008-2015 Nokia Networks
2# Copyright 2016- Robot Framework Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
16import os 1ab
17import sqlite3 1ab
18import time 1ab
20from ..preferences.settings import SETTINGS_DIRECTORY 1ab
21from ..spec.iteminfo import LibraryKeywordInfo 1ab
22from ..lib.robot.utils import system_decode 1ab
24CREATION_SCRIPT = """\ 1ab
25CREATE TABLE libraries (id INTEGER PRIMARY KEY,
26 name TEXT,
27 doc_format TEXT,
28 arguments TEXT,
29 last_updated REAL);
30CREATE TABLE keywords (name TEXT,
31 doc TEXT,
32 arguments TEXT,
33 library_name TEXT,
34 library INTEGER,
35 FOREIGN KEY(library) REFERENCES libraries(id));
36"""
38DATABASE_FILE = os.path.join(system_decode(SETTINGS_DIRECTORY), 1ab
39 'librarykeywords.db')
42def _create_database(): 1ab
43 print('Creating librarykeywords database to "%s"' % DATABASE_FILE)
45 connection = sqlite3.connect(DATABASE_FILE)
46 connection.executescript(CREATION_SCRIPT)
47 connection.commit()
48 connection.close()
51def _validate_database(): 1ab
52 connection = sqlite3.connect(DATABASE_FILE)
53 try:
54 connection.execute('select id, name, doc_format, arguments,'
55 ' last_updated from libraries')
56 connection.execute('select name, doc, arguments, library_name,'
57 ' library from keywords')
58 finally:
59 connection.close()
62def initialize_database(): 1ab
63 if not os.path.exists(SETTINGS_DIRECTORY): 63 ↛ 64line 63 didn't jump to line 64 because the condition on line 63 was never true
64 os.makedirs(SETTINGS_DIRECTORY)
65 if not os.path.exists(DATABASE_FILE): 65 ↛ 66line 65 didn't jump to line 66 because the condition on line 65 was never true
66 _create_database()
67 else:
68 try:
69 _validate_database()
70 except sqlite3.DatabaseError as err:
71 print('removing database "%s"' % DATABASE_FILE)
72 print('error during database validation "%s"' % err)
73 try:
74 os.remove(DATABASE_FILE)
75 except Exception as err:
76 print('failed to remove database "%s"' % DATABASE_FILE)
77 raise err
78 _create_database()
81class LibraryDatabase(object): 1ab
83 def __init__(self, database): 1ab
84 self._connection = sqlite3.connect(database, timeout=30.0) 2a d e f g h i j k ; l = ? @ [ ] ^ 6 m n 7 o p _ ` { : | q r s t u v w x y z A B C D E F G H I J K L M N O P Q R - c S T U V W X Y Z ab0 1 2 3 4 } ~ 5
86 def create_database(self): 1ab
87 self._cursor().executescript(CREATION_SCRIPT) 2a d e f g h i j k ; l = ? @ [ ] ^ 6 m n 7 o p _ ` { : | q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ab0 1 2 3 4 } ~ 5
88 self._connection.commit() 1adefghijk;l=?@[]^6mn7op_`{:|qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234}~5
90 def _cursor(self): 1ab
91 return self._connection.cursor() 2a d e f g h i j k ; l = ? @ [ ] ^ 6 m n 7 o p _ ` { : | q r s t u v w x y z A B C D E F G H I J K L M N O P Q R - . c S T U V W X Y Z ab0 1 2 3 4 } ~ 5 8 9 ! # $ , / % ' ( * + )
93 def close(self): 1ab
94 self._connection.close() 2a bbd e f g h i j k l 6 m n 7 o p : q r s t u v w x y z A B C D E F G H I J K L M N O P Q R - . c S T U V W X Y Z 0 1 2 3 4 5 cb
96 def insert_library_keywords(self, library_name, library_arguments, 1ab
97 keywords):
98 library_doc_format = "ROBOT" 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
99 if len(keywords) > 0: 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
100 library_doc_format = keywords[0].doc_format 1adefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234589!#$%'()
102 cur = self._cursor() 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
103 old_versions = cur.execute('select id from libraries where name = ? ' 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
104 'and arguments = ?',
105 (library_name,
106 str(library_arguments))).fetchall()
107 cur.executemany('delete from keywords where library = ?', old_versions) 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
108 cur.executemany('delete from libraries where id = ?', old_versions) 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
109 lib = self._insert_library(library_name, library_doc_format, 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
110 library_arguments, cur)
111 keyword_values = [[kw.name, kw.doc, u' | '.join(kw.arguments), 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
112 kw.source,
113 lib[0]] for kw in keywords if kw is not None]
114 self._insert_library_keywords(keyword_values, cur) 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
115 self._connection.commit() 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
117 def update_library_timestamp(self, name, arguments, milliseconds=None): 1ab
118 self._cursor().execute('update libraries set last_updated = ?' 1a-.c
119 ' where name = ? and arguments = ?',
120 (milliseconds or time.time(), name,
121 str(arguments)))
122 self._connection.commit() 1a-.c
124 def fetch_library_keywords(self, library_name, library_arguments): 1ab
125 lib = self._fetch_lib(library_name, library_arguments, self._cursor()) 1a-.c89!#$/%'(*+)
126 if lib is None: 1a-.c89!#$/%'(*+)
127 return [] 1/'(*+)
128 return [LibraryKeywordInfo(name, doc, lib[2], library_name, 1a-.c89!#$%
129 arguments.split(u' | ') if arguments else [])
130 for name, doc, arguments, library_name in
131 self._connection.execute('select name, doc, arguments,'
132 ' library_name from keywords where'
133 ' library = ?', [lib[0]])]
135 def library_exists(self, library_name, library_arguments): 1ab
136 return self._fetch_lib(library_name, library_arguments, 1,
137 self._cursor()) is not None
139 def get_library_last_updated(self, library_name, library_arguments): 1ab
140 lib = self._fetch_lib(library_name, library_arguments, self._cursor()) 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQR-cSTUVWXYZ012345
141 if not lib: 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQR-cSTUVWXYZ012345
142 return 0.0 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345
143 return lib[4] 1-c
145 def _insert_library(self, name, doc_format, arguments, cursor): 1ab
146 cursor.execute('insert into libraries values (null, ?, ?, ?, ?)', 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
147 (name, doc_format, str(arguments), time.time()))
148 return self._fetch_lib(name, arguments, cursor) 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)
150 @staticmethod 1ab
151 def _fetch_lib(name, arguments, cursor): 1ab
152 t = cursor.execute('select max(last_updated) from libraries where name' 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQR-.cSTUVWXYZ01234589!#$,/%'(*+)
153 ' = ? and arguments = ?',
154 (name, str(arguments))).fetchone()[0]
155 return cursor.execute('select * from libraries where name = ?' 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQR-.cSTUVWXYZ01234589!#$,/%'(*+)
156 ' and arguments = ? and last_updated = ?',
157 (name, str(arguments), t)).fetchone()
159 @staticmethod 1ab
160 def _insert_library_keywords(data, cursor): 1ab
161 cursor.executemany('insert into keywords values (?, ?, ?, ?, ?)', data) 1adefghijkl6mn7opqrstuvwxyzABCDEFGHIJKLMNOPQRcSTUVWXYZ01234589!#$,%'(*+)