Skip to content
Snippets Groups Projects
Commit 11566365 authored by Anders H. Rebner's avatar Anders H. Rebner
Browse files

#103 Tabell- og kodebokGUI-navn endret

parent 4e70cd9b
No related branches found
No related tags found
1 merge request!58#103 Tabell- og kodebokGUI-navn endret
Pipeline #79381 passed
......@@ -13,11 +13,11 @@ CONNAME = "SOIDB"
DBTYPE = "QSQLITE"
class CodeBookTableView(QTableView):
"""TableView with a model of the 'codebook'-table from database.
class CodebookTableView(QTableView):
"""TableView with a model of the 'Codebook'-table from database.
This modified QTableView creates a CodeBookTableModel, which reads the
codebook-table. User can add, edit, delete and insert entries through this
This modified QTableView creates a CodebookTableModel, which reads the
Codebook-table. User can add, edit, delete and insert entries through this
view.
Parameter 'database' should be an instance of soitool.database.Database,
......@@ -39,7 +39,7 @@ class CodeBookTableView(QTableView):
self.verticalHeader().hide()
# Create and set model:
model = CodeBookTableModel()
model = CodebookTableModel()
self.setModel(model)
self.setEditTriggers(self.DoubleClicked)
......@@ -101,15 +101,11 @@ class CodeBookTableView(QTableView):
self.resizeColumnsToContents()
class CodeBookTableModel(QSqlTableModel):
class CodebookTableModel(QSqlTableModel):
"""Editable QSqlTableModel of database-table 'CodeBook'.
This modified QSqlTableModel writes to database
when a value is changed by the view.
The last row is used by the view to insert a new database record,
therefore, only column 'Word' (Primary key) is editable in this row.
All columns except 'Code' are editable.
This modified QSqlTableModel writes to database when a value is changed
in the view. All columns except 'Code' are editable.
This class initializes by connecting to database and selecting table.
"""
......
......@@ -10,7 +10,7 @@ from PySide2.QtWidgets import (
QWidget,
)
from PySide2.QtCore import Qt
from soitool.codebook_model_view import CodeBookTableModel, CodeBookTableView
from soitool.codebook_model_view import CodebookTableModel, CodebookTableView
class CodebookRowAdder(QWidget):
......@@ -43,7 +43,7 @@ class CodebookRowAdder(QWidget):
# Raise error if argument is invalid
if codebook_view is not None and not isinstance(
codebook_view, CodeBookTableView
codebook_view, CodebookTableView
):
raise ValueError(
"Invalid value for argument 'codebook_view': "
......@@ -202,4 +202,4 @@ class CodebookRowAdder(QWidget):
# If a view is used, create and set a new, updated model
if self.codebook_view is not None:
self.codebook_view.setModel(CodeBookTableModel())
self.codebook_view.setModel(CodebookTableModel())
"""Module containing a widget for viewing and editing codebook."""
from PySide2.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout
from soitool.codebook_model_view import CodeBookTableView
from soitool.codebook_model_view import CodebookTableView
from soitool.codebook_row_adder import CodebookRowAdder
......@@ -11,7 +11,7 @@ class CodebookWidget(QWidget):
super().__init__()
# Create widgets
self.view = CodeBookTableView(database)
self.view = CodebookTableView(database)
self.row_adder = CodebookRowAdder(database, self.view)
self.create_and_set_layouts()
......
......@@ -16,7 +16,7 @@ SECONDS_IN_24H = 24 * 60 * 60
# DDL-statements for creating tables
CODEBOOK = (
"CREATE TABLE CodeBook("
"CREATE TABLE Codebook("
"Word VARCHAR PRIMARY KEY NOT NULL CHECK(length(Word) > 0), "
"Category VARCHAR, "
"Type VARCHAR DEFAULT 'Stor' CHECK(Type='Stor' OR Type='Liten'), "
......@@ -27,7 +27,7 @@ CATEGORYWORDS = (
"Word VARCHAR PRIMARY KEY, "
"Category VARCHAR NOT NULL CHECK(length(Category) > 0))"
)
BYHEART = "CREATE TABLE ByHeart(Word VARCHAR PRIMARY KEY)"
SOICODEWORDS = "CREATE TABLE SOICodewords(Word VARCHAR PRIMARY KEY)"
LASTUPDATED = "CREATE TABLE LastUpdated(Timestamp DATETIME PRIMARY KEY)"
......@@ -39,7 +39,7 @@ class Database:
is given. Connects to existing db if found, creates new db if not.
If db is created, tables are created and filled.
Holds a QTimer that requests an update of CodeBook on every timeout.
Holds a QTimer that requests an update of Codebook on every timeout.
"""
def __init__(self, db_path=DBPATH):
......@@ -65,8 +65,8 @@ class Database:
self.conn.row_factory = sqlite3.Row # Enables row["columnName"]
def create_tables(self):
"""Create tables CodeBook, CategoryWords and ByHeart."""
stmts = [CODEBOOK, CATEGORYWORDS, BYHEART, LASTUPDATED]
"""Create tables Codebook, CategoryWords and SOICodewords."""
stmts = [CODEBOOK, CATEGORYWORDS, SOICODEWORDS, LASTUPDATED]
for stmt in stmts:
self.conn.execute(stmt)
......@@ -76,13 +76,13 @@ class Database:
def fill_tables(self):
"""Fill tables with testdata."""
self.fill_codebook()
self.fill_by_heart()
self.fill_soi_codewords()
self.fill_category_words()
self.fill_last_updated()
self.conn.commit()
def fill_codebook(self):
"""Read data from long_codebook.json and fill DB-table CodeBook."""
"""Read data from long_codebook.json and fill DB-table Codebook."""
file_path = os.path.join(CURDIR, "testdata/long_codebook.json")
# Load json as dict
......@@ -96,7 +96,7 @@ class Database:
# Insert data in db
stmt = (
"INSERT INTO CodeBook(Word, Category, Type, Code)"
"INSERT INTO Codebook(Word, Category, Type, Code)"
"VALUES(?,?,?,?)"
)
......@@ -106,13 +106,13 @@ class Database:
(word["word"], word["category"], word["type"], codes.pop()),
)
def fill_by_heart(self):
"""Read data from ByHeart.txt and fill DB-table ByHeart."""
file_path = os.path.join(CURDIR, "testdata/ByHeart.txt")
def fill_soi_codewords(self):
"""Read data from SOICodewords.txt and fill DB-table SOICodewords."""
file_path = os.path.join(CURDIR, "testdata/SOICodewords.txt")
file = open(file_path, "r", encoding="utf-8")
# Loop through words on file and insert them into ByHeart-table
stmt = "INSERT INTO ByHeart(Word) VALUES(?)"
# Loop through words on file and insert them into SOICodewords-table
stmt = "INSERT INTO SOICodewords(Word) VALUES(?)"
for expr in file:
self.conn.execute(stmt, (expr.rstrip(),))
file.close()
......@@ -184,7 +184,7 @@ class Database:
codebook : list (of dicts)
[{'word': str, 'type': str, 'category': str, 'code': str}]
"""
stmt = "SELECT * FROM (SELECT * FROM CodeBook"
stmt = "SELECT * FROM (SELECT * FROM Codebook"
if sort == CodebookSort.WORD:
stmt += " ORDER BY Word)"
......@@ -218,7 +218,7 @@ class Database:
def update_codebook(self):
"""Update codes in DB."""
# Get all the words (PK)
stmt = "SELECT Word FROM CodeBook"
stmt = "SELECT Word FROM Codebook"
words = self.conn.execute(stmt).fetchall()
# Get number of entries
number_of_entries = len(words)
......@@ -226,7 +226,7 @@ class Database:
code_len = soitool.coder.get_code_length_needed(number_of_entries)
codes = soitool.coder.get_code_set(number_of_entries, code_len)
# Statement for update
stmt = "UPDATE CodeBook SET Code = ?"
stmt = "UPDATE Codebook SET Code = ?"
# Inserting NULL into Code column because of UNIQUE constraint
self.conn.execute(stmt, (None,))
# Fill Code column with new codes
......@@ -238,7 +238,7 @@ class Database:
# Save changes in db
self.conn.commit()
print("Code in CodeBook updated")
print("Code in Codebook updated")
def seconds_to_next_update(self, period):
"""
......@@ -303,9 +303,9 @@ class Database:
for combination of letters and digits.
"""
# Get length of codes and calculate needed length of codes
stmt = "SELECT COUNT(*) FROM CodeBook"
stmt = "SELECT COUNT(*) FROM Codebook"
number_of_entries = self.conn.execute(stmt).fetchall()[0][0]
stmt = "SELECT Code FROM CodeBook"
stmt = "SELECT Code FROM Codebook"
# In special case where table is empty
if number_of_entries <= 0:
raise ValueError("Can't add code to table with no words.")
......@@ -334,6 +334,6 @@ class Database:
while code in codes:
code = soitool.coder.get_code(needed_code_len, mode)
# Insert code to the param word in db
stmt = "UPDATE CodeBook SET Code = ? WHERE Word = ?"
stmt = "UPDATE Codebook SET Code = ? WHERE Word = ?"
self.conn.execute(stmt, (code, word))
self.conn.commit()
......@@ -19,7 +19,7 @@ from soitool.soi_workspace_widget import SOIWorkspaceWidget
from soitool.codebook_to_pdf import generate_codebook_pdf
from soitool.dialog_wrappers import exec_info_dialog
from soitool.codebook_widget import CodebookWidget
from soitool.codebook_model_view import CodeBookTableModel
from soitool.codebook_model_view import CodebookTableModel
from soitool.database import Database, DBPATH
from soitool.help_actions import ShortcutsHelpDialog, BasicUsageHelpDialog
from soitool.serialize_export_import_soi import (
......@@ -271,7 +271,7 @@ class MainWindow(QMainWindow):
view = self.tabs.widget(i).view
view.setModel(None)
regenerate()
view.setModel(CodeBookTableModel())
view.setModel(CodebookTableModel())
break
else:
regenerate()
......
File moved
......@@ -28,9 +28,9 @@ class DatabaseTest(unittest.TestCase):
self.assertIsNotNone(self.database)
def test_by_heart(self):
"""Assert contents of table ByHeart in DB matches testdata."""
"""Assert contents of table SOICodewords in DB matches testdata."""
# Open and read file:
file_path = os.path.join(TESTDATA_PATH, "ByHeart.txt")
file_path = os.path.join(TESTDATA_PATH, "SOICodewords.txt")
f = open(file_path, "r", encoding="utf-8")
file_content = f.read()
......@@ -39,7 +39,7 @@ class DatabaseTest(unittest.TestCase):
no_of_expr = len(expressions)
# Retrieve expressions from DB:
stmt = "SELECT * FROM ByHeart"
stmt = "SELECT * FROM SOICodewords"
queried = self.database.conn.execute(stmt).fetchall()
# Assert equal amount of expressions in table and file
......@@ -96,7 +96,7 @@ class DatabaseTest(unittest.TestCase):
f.close()
# Get data from db
stmt = "SELECT * FROM CodeBook ORDER BY Word"
stmt = "SELECT * FROM Codebook ORDER BY Word"
actual = self.database.conn.execute(stmt).fetchall()
# Check same lenght
......@@ -211,7 +211,7 @@ class DatabaseTest(unittest.TestCase):
def test_update_codebook(self):
"""Test that the codes get updated."""
# Get entries before and after update
stmt = "SELECT Word, Code FROM CodeBook ORDER BY Word"
stmt = "SELECT Word, Code FROM Codebook ORDER BY Word"
old_entries = self.database.conn.execute(stmt).fetchall()
self.database.update_codebook()
new_entries = self.database.conn.execute(stmt).fetchall()
......@@ -228,20 +228,20 @@ class DatabaseTest(unittest.TestCase):
def test_code_length_extended_on_update(self):
"""Test code length gets extended when number of entries makes it."""
three_letter_len = 26 ** 2
stmt_count = "SELECT COUNT(*) FROM CodeBook"
stmt_count = "SELECT COUNT(*) FROM Codebook"
number_of_entries = self.database.conn.execute(stmt_count).fetchall()[
0
][0]
# Codes only gets extended when number of entries pass 26**x
if number_of_entries == (three_letter_len):
# Get length of current codes
stmt_code = "SELECT Code FROM CodeBook"
stmt_code = "SELECT Code FROM Codebook"
code_len = len(
self.database.conn.execute(stmt_code).fetchall()[0][0]
)
self.assertEqual(2, code_len)
# Insert a entry to pass 26**2 entries
stmt = "INSERT INTO CodeBook (Word, Category, Code) VALUES (?,?,?)"
stmt = "INSERT INTO Codebook (Word, Category, Code) VALUES (?,?,?)"
self.database.conn.execute(stmt, ("676", "676", None))
self.database.update_codebook()
# Check that entry got inserted
......@@ -282,12 +282,12 @@ class DatabaseTest(unittest.TestCase):
self.assertEqual(0, self.database.seconds_to_next_update(1))
def test_add_code(self):
"""Test add a single code to CodeBook."""
"""Test add a single code to Codebook."""
testdata = ("Testword", "Testcategory")
stmt = "INSERT INTO CodeBook (Word, Category) VALUES (?,?)"
stmt = "INSERT INTO Codebook (Word, Category) VALUES (?,?)"
self.database.conn.execute(stmt, (testdata[0], testdata[1]))
self.database.add_code_to(testdata[0])
stmt = "SELECT Code FROM CodeBook WHERE Word = ?"
stmt = "SELECT Code FROM Codebook WHERE Word = ?"
code = self.database.conn.execute(stmt, (testdata[0],)).fetchall()[0][
0
]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment