Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@

# Import reformatting
cff1e87a0d742be463d820382f467115fb18c8a2

# Reformat files previously excluded from ruff
ca41d10a8aa8bbd5f6715896e5878e4f0789af93
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ clean-test: ## remove test and coverage artifacts
rm -f .coverage
rm -fr htmlcov/

lint:
pre-commit run --all-files

migrations:
python tests/testapp/manage.py makemigrations

Expand Down
42 changes: 15 additions & 27 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def process_docstring(app, what, name, obj, options, lines):
for field in fields:
# Skip ManyToOneRel and ManyToManyRel fields
# which have no 'verbose_name' or 'help_text'
if not hasattr(field, 'verbose_name'):
if not hasattr(field, "verbose_name"):
continue

# Decode and strip any html out of the field's help text
Expand All @@ -77,24 +77,20 @@ def process_docstring(app, what, name, obj, options, lines):
if help_text:
# Add the model field to the end of the docstring as a param
# using the help text as the description
lines.append(u':param %s: %s' % (field.attname, help_text))
lines.append(":param %s: %s" % (field.attname, help_text))
else:
# Add the model field to the end of the docstring as a param
# using the verbose name as the description
lines.append(u':param %s: %s' % (field.attname, verbose_name))
lines.append(":param %s: %s" % (field.attname, verbose_name))

# Add the field's type to the docstring
if isinstance(field, models.ForeignKey):
to = field.remote_field.model
lines.append(
u':type %s: %s to :class:`~%s`'
% (field.attname, type(field).__name__, to)
":type %s: %s to :class:`~%s`" % (field.attname, type(field).__name__, to)
)
else:
lines.append(
u':type %s: %s'
% (field.attname, type(field).__name__)
)
lines.append(":type %s: %s" % (field.attname, type(field).__name__))

return lines

Expand All @@ -106,18 +102,18 @@ def process_docstring(app, what, name, obj, options, lines):
extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode"]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
source_suffix = [".rst"]

# The master toctree document.
master_doc = 'index'
master_doc = "index"

# General information about the project.
project = u"Morango developer documentation"
copyright = u"2020 Learning Equality"
project = "Morango developer documentation"
copyright = "2020 Learning Equality"

# The version info for the project you're documenting, acts as replacement
# for |version| and |release|, also used in various other places throughout
Expand All @@ -140,7 +136,7 @@ def process_docstring(app, what, name, obj, options, lines):

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']
exclude_patterns = ["_build"]

# The reST default role (used for this markup: `text`) to use for all
# documents.
Expand All @@ -158,7 +154,7 @@ def process_docstring(app, what, name, obj, options, lines):
# show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
pygments_style = "sphinx"

# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
Expand Down Expand Up @@ -257,18 +253,16 @@ def setup(app):
# html_file_suffix = None

# Output file base name for HTML help builder.
htmlhelp_basename = 'morangodoc'
htmlhelp_basename = "morangodoc"


# -- Options for LaTeX output ------------------------------------------

latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
# 'papersize': 'letterpaper',

# The font size ('10pt', '11pt' or '12pt').
# 'pointsize': '10pt',

# Additional stuff for the LaTeX preamble.
# 'preamble': '',
}
Expand All @@ -277,9 +271,7 @@ def setup(app):
# (source start file, target name, title, author, documentclass
# [howto/manual]).
latex_documents = [
('index', 'morango.tex',
u'morango Documentation',
u'Learning Equality', 'manual'),
("index", "morango.tex", "morango Documentation", "Learning Equality", "manual"),
]

# The name of an image file (relative to this directory) to place at
Expand Down Expand Up @@ -307,11 +299,7 @@ def setup(app):

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'morango',
u'morango Documentation',
[u'Learning Equality'], 1)
]
man_pages = [("index", "morango", "morango Documentation", ["Learning Equality"], 1)]

# If true, show URL addresses after external links.
# man_show_urls = False
Expand Down Expand Up @@ -346,4 +334,4 @@ def setup(app):
# If true, do not generate a @detailmenu in the "Top" node's menu.
# texinfo_no_detailmenu = False

suppress_warnings = ['image.nonlocal_uri']
suppress_warnings = ["image.nonlocal_uri"]
33 changes: 16 additions & 17 deletions morango/sync/backends/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
import logging
from contextlib import contextmanager

from .base import BaseSQLWrapper
from .utils import get_pk_field
from morango.errors import MorangoDatabaseError
from morango.models.core import Buffer
from morango.models.core import RecordMaxCounter
from morango.models.core import RecordMaxCounterBuffer
from morango.models.core import Store
from morango.utils import SETTINGS

from .base import BaseSQLWrapper
from .utils import get_pk_field

# advisory lock integers for locking partitions
LOCK_ALL_PARTITIONS = 1
Expand All @@ -23,9 +23,7 @@

class SQLWrapper(BaseSQLWrapper):
backend = "postgresql"
create_temporary_table_template = (
"CREATE TEMP TABLE {name} ({fields}) ON COMMIT DROP"
)
create_temporary_table_template = "CREATE TEMP TABLE {name} ({fields}) ON COMMIT DROP"

def _is_transaction_isolation_error(self, error):
"""
Expand All @@ -36,7 +34,7 @@ def _is_transaction_isolation_error(self, error):
from psycopg2.extensions import TransactionRollbackError

# Django can wrap errors, adding it to the `__cause__` attribute
for e in (error, getattr(error, '__cause__', None)):
for e in (error, getattr(error, "__cause__", None)):
if isinstance(e, TransactionRollbackError):
return True
return False
Expand All @@ -55,11 +53,15 @@ def _set_transaction_repeatable_read(self):
# before any reading/writing operations have taken place, which includes creating
# savepoints
if self.connection.in_atomic_block:
raise MorangoDatabaseError("Unable to set transaction isolation during a transaction")
raise MorangoDatabaseError(
"Unable to set transaction isolation during a transaction"
)

for savepoint_id in self.connection.savepoint_ids:
if savepoint_id is not None:
raise MorangoDatabaseError("Unable to set transaction isolation when savepoints have been created")
raise MorangoDatabaseError(
"Unable to set transaction isolation when savepoints have been created"
)

# ensure the postgres database wrapper loads the isolation level, which requires it to
# connection to the database.
Expand All @@ -70,7 +72,9 @@ def _set_transaction_repeatable_read(self):

try:
self.connection.isolation_level = ISOLATION_LEVEL_REPEATABLE_READ
self.connection.connection.set_session(isolation_level=ISOLATION_LEVEL_REPEATABLE_READ, autocommit=False)
self.connection.connection.set_session(
isolation_level=ISOLATION_LEVEL_REPEATABLE_READ, autocommit=False
)
yield
finally:
self.connection.isolation_level = existing_isolation_level
Expand Down Expand Up @@ -99,9 +103,7 @@ def _prepare_with_values(self, name, fields, db_values):
def _prepare_casted_fields(self, fields):
return ", ".join(
map(
lambda f: "{f}::{type}".format(
f=f.column, type=f.rel_db_type(self.connection)
),
lambda f: "{f}::{type}".format(f=f.column, type=f.rel_db_type(self.connection)),
fields,
)
)
Expand Down Expand Up @@ -255,17 +257,14 @@ def _dequeuing_merge_conflict_buffer(self, cursor, current_id, transfersession_i
buffer=Buffer._meta.db_table,
rmcb=RecordMaxCounterBuffer._meta.db_table,
store=Store._meta.db_table,
rmc=RecordMaxCounter._meta.db_table,
transfer_session_id=transfersession_id,
current_instance_id=current_id.id,
current_instance_counter=current_id.counter,
)

cursor.execute(merge_conflict_store)

def _dequeuing_update_rmcs_last_saved_by(
self, cursor, current_id, transfersession_id
):
def _dequeuing_update_rmcs_last_saved_by(self, cursor, current_id, transfersession_id):
# update or create rmc for merge conflicts with local instance id
merge_conflict_store = """
WITH new_values as
Expand Down Expand Up @@ -470,7 +469,7 @@ def _execute_lock(self, key1, key2=None, unlock=False, session=False, shared=Fal
xact_="" if session else "xact_",
lock="unlock" if unlock else "lock",
_shared="_shared" if shared else "",
keys=", ".join(["%s"] * len(keys))
keys=", ".join(["%s"] * len(keys)),
)

with self.connection.cursor() as c:
Expand Down
24 changes: 8 additions & 16 deletions morango/sync/backends/sqlite.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from .base import BaseSQLWrapper
from .utils import calculate_max_sqlite_variables
from .utils import get_pk_field
from morango.models.core import Buffer
from morango.models.core import RecordMaxCounter
from morango.models.core import RecordMaxCounterBuffer
from morango.models.core import Store

from .base import BaseSQLWrapper
from .utils import calculate_max_sqlite_variables
from .utils import get_pk_field


class SQLWrapper(BaseSQLWrapper):
backend = "sqlite"
Expand Down Expand Up @@ -51,9 +52,7 @@ def _bulk_insert(self, cursor, table_name, fields, db_values):
for x in range(0, len(db_values), num_of_values_able_to_insert)
]
for value_chunk in value_chunks:
super(SQLWrapper, self)._bulk_insert(
cursor, table_name, fields, value_chunk
)
super(SQLWrapper, self)._bulk_insert(cursor, table_name, fields, value_chunk)

def _bulk_update(self, cursor, table_name, fields, db_values):
"""
Expand All @@ -64,9 +63,7 @@ def _bulk_update(self, cursor, table_name, fields, db_values):
# calculate and create equal sized chunks of data to update incrementally
# for every field we're updating, we'll require 3 parameters
num_update_fields = len(fields) - 1
num_of_rows_able_to_update = (
calculate_max_sqlite_variables() // num_update_fields // 3
)
num_of_rows_able_to_update = calculate_max_sqlite_variables() // num_update_fields // 3
num_of_values_able_to_update = num_of_rows_able_to_update * len(fields)
value_chunks = [
db_values[x : x + num_of_values_able_to_update]
Expand Down Expand Up @@ -100,9 +97,7 @@ def _bulk_update(self, cursor, table_name, fields, db_values):
table_name=table_name,
set_sql=set_sql[:-1],
pk_field=pk.column,
placeholder_str="({})".format(
",".join("%s" for _ in range(len(pk_params)))
),
placeholder_str="({})".format(",".join("%s" for _ in range(len(pk_params)))),
)
# use DB-APIs parameter substitution (2nd parameter expects a sequence)
cursor.execute(update, params)
Expand Down Expand Up @@ -196,16 +191,13 @@ def _dequeuing_merge_conflict_buffer(self, cursor, current_id, transfersession_i
buffer=Buffer._meta.db_table,
rmcb=RecordMaxCounterBuffer._meta.db_table,
store=Store._meta.db_table,
rmc=RecordMaxCounter._meta.db_table,
transfer_session_id=transfersession_id,
current_instance_id=current_id.id,
current_instance_counter=current_id.counter,
)
cursor.execute(merge_conflict_store)

def _dequeuing_update_rmcs_last_saved_by(
self, cursor, current_id, transfersession_id
):
def _dequeuing_update_rmcs_last_saved_by(self, cursor, current_id, transfersession_id):
# update or create rmc for merge conflicts with local instance id
merge_conflict_store = """REPLACE INTO {rmc} (instance_id, counter, store_model_id)
SELECT '{current_instance_id}', {current_instance_counter}, store.id
Expand Down
Loading
Loading