summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Halley <halley@dnspython.org>2020-08-18 19:23:22 -0700
committerBob Halley <halley@dnspython.org>2020-08-18 19:23:22 -0700
commit1b2af789ffc6c8da54dda199a94c9d79797d356c (patch)
tree0b86d2bfd79fd86fa56b8007d63521cdf6d3a0e8
parent279dbec2722bd9836b1adf76db5136aeb346421e (diff)
downloaddnspython-1b2af789ffc6c8da54dda199a94c9d79797d356c.tar.gz
store reference to manager in all txns; add origin_information()
-rw-r--r--dns/masterfile.py10
-rw-r--r--dns/transaction.py22
-rw-r--r--dns/versioned.py13
-rw-r--r--dns/zone.py18
-rw-r--r--tests/test_transaction.py9
5 files changed, 49 insertions, 23 deletions
diff --git a/dns/masterfile.py b/dns/masterfile.py
index 30553b5..66bb6a3 100644
--- a/dns/masterfile.py
+++ b/dns/masterfile.py
@@ -42,19 +42,15 @@ class Reader:
"""Read a DNS master file into a transaction."""
- def __init__(self, tok, origin, rdclass, relativize, txn,
- allow_include=False):
- if isinstance(origin, str):
- origin = dns.name.from_text(origin)
+ def __init__(self, tok, rdclass, txn, allow_include=False):
self.tok = tok
- self.current_origin = origin
- self.relativize = relativize
+ (self.zone_origin, self.relativize) = txn.manager.origin_information()
+ self.current_origin = self.zone_origin
self.last_ttl = 0
self.last_ttl_known = False
self.default_ttl = 0
self.default_ttl_known = False
self.last_name = self.current_origin
- self.zone_origin = origin
self.zone_rdclass = rdclass
self.txn = txn
self.saved_state = []
diff --git a/dns/transaction.py b/dns/transaction.py
index aec0662..eae2920 100644
--- a/dns/transaction.py
+++ b/dns/transaction.py
@@ -20,13 +20,30 @@ class TransactionManager:
def writer(self, replacement=False):
"""Begin a writable transaction.
- *replacement*, a `bool`. If `True`, the content of the
+ *replacement*, a ``bool``. If `True`, the content of the
transaction completely replaces any prior content. If False,
the default, then the content of the transaction updates the
existing content.
"""
raise NotImplementedError # pragma: no cover
+ def origin_information(self):
+ """Returns an (origin: ``dns.name.Name``, relativize: ``bool``) tuple
+ giving the absolute name of the default origin for any
+ relative domain names, and whether names should be relativized
+ to that origin.
+
+ If the returned name is `None`, then no origin information is
+ available.
+
+ This information is used by code working with transactions to
+ allow it to coordinate relativization. The transaction code
+ itself takes what it gets (i.e. does not change name
+ relativity).
+
+ """
+ raise NotImplementedError # pragma: no cover
+
class DeleteNotExact(dns.exception.DNSException):
"""Existing data did not match data specified by an exact delete."""
@@ -42,7 +59,8 @@ class AlreadyEnded(dns.exception.DNSException):
class Transaction:
- def __init__(self, replacement=False, read_only=False):
+ def __init__(self, manager, replacement=False, read_only=False):
+ self.manager = manager
self.replacement = replacement
self.read_only = read_only
self._ended = False
diff --git a/dns/versioned.py b/dns/versioned.py
index e070c1a..99c30e4 100644
--- a/dns/versioned.py
+++ b/dns/versioned.py
@@ -234,7 +234,7 @@ class Zone(dns.zone.Zone):
raise KeyError('serial not found')
else:
version = self._versions[-1]
- txn = Transaction(False, self, version)
+ txn = Transaction(self, False, version)
self._readers.add(txn)
return txn
@@ -252,7 +252,7 @@ class Zone(dns.zone.Zone):
# give up the lock, so that we hold the lock as
# short a time as possible. This is why we call
# _setup_version() below.
- self._write_txn = Transaction(replacement, self)
+ self._write_txn = Transaction(self, replacement)
# give up our exclusive right to make a Transaction
self._write_event = None
break
@@ -403,12 +403,15 @@ class Zone(dns.zone.Zone):
class Transaction(dns.transaction.Transaction):
- def __init__(self, replacement, zone, version=None):
+ def __init__(self, zone, replacement, version=None):
read_only = version is not None
- super().__init__(replacement, read_only)
- self.zone = zone
+ super().__init__(zone, replacement, read_only)
self.version = version
+ @property
+ def zone(self):
+ return self.manager
+
def _setup_version(self):
assert self.version is None
self.version = WritableVersion(self.zone, self.replacement)
diff --git a/dns/zone.py b/dns/zone.py
index e85603b..11c4c33 100644
--- a/dns/zone.py
+++ b/dns/zone.py
@@ -643,10 +643,13 @@ class Zone(dns.transaction.TransactionManager):
raise NoNS
def reader(self):
- return Transaction(False, True, self)
+ return Transaction(self, False, True)
def writer(self, replacement=False):
- return Transaction(replacement, False, self)
+ return Transaction(self, replacement, False)
+
+ def origin_information(self):
+ return (self.origin, self.relativize)
class Transaction(dns.transaction.Transaction):
@@ -654,11 +657,14 @@ class Transaction(dns.transaction.Transaction):
_deleted_rdataset = dns.rdataset.Rdataset(dns.rdataclass.ANY,
dns.rdatatype.ANY)
- def __init__(self, replacement, read_only, zone):
- super().__init__(replacement, read_only)
- self.zone = zone
+ def __init__(self, zone, replacement, read_only):
+ super().__init__(zone, replacement, read_only)
self.rdatasets = {}
+ @property
+ def zone(self):
+ return self.manager
+
def _get_rdataset(self, name, rdclass, rdtype, covers):
if rdclass != self.zone.rdclass:
raise ValueError(f'class {rdclass} != ' +
@@ -805,7 +811,7 @@ def from_text(text, origin=None, rdclass=dns.rdataclass.IN,
zone = zone_factory(origin, rdclass, relativize=relativize)
with zone.writer(True) as txn:
tok = dns.tokenizer.Tokenizer(text, filename, idna_codec=idna_codec)
- reader = dns.masterfile.Reader(tok, origin, rdclass, relativize, txn,
+ reader = dns.masterfile.Reader(tok, rdclass, txn,
allow_include=allow_include)
try:
reader.read()
diff --git a/tests/test_transaction.py b/tests/test_transaction.py
index 3dcaba0..bf7b130 100644
--- a/tests/test_transaction.py
+++ b/tests/test_transaction.py
@@ -18,14 +18,17 @@ class DB(dns.transaction.TransactionManager):
self.rdatasets = {}
def reader(self):
- return Transaction(False, True, self)
+ return Transaction(self, False, True)
def writer(self, replacement=False):
- return Transaction(replacement, False, self)
+ return Transaction(self, replacement, False)
+
+ def origin_information(self):
+ return (None, True)
class Transaction(dns.transaction.Transaction):
- def __init__(self, replacement, read_only, db):
+ def __init__(self, db, replacement, read_only):
super().__init__(replacement)
self.db = db
self.rdatasets = {}