Specify column names during the PowerDNS backends InsertFromSelect's

Closes-Bug: 1263081
Closes-Bug: 1262837
Change-Id: I635c0767df792c5980ad345fe2714aae046060f3
This commit is contained in:
Kiall Mac Innes 2013-12-20 12:11:09 +00:00
parent 387acaccf3
commit f3df379599
2 changed files with 59 additions and 24 deletions

View File

@ -18,7 +18,6 @@
import base64
from sqlalchemy import func
from sqlalchemy.sql import select
from sqlalchemy.sql.expression import null
from sqlalchemy.sql.expression import and_
from sqlalchemy.orm import exc as sqlalchemy_exceptions
from oslo.config import cfg
@ -74,11 +73,20 @@ class PowerDNSBackend(base.Backend):
# NOTE(kiall): Prepare and execute query to install this TSIG Key on
# every domain. We use a manual query here since anything
# else would be impossibly slow.
query_select = select([null(),
models.Domain.__table__.c.id,
"'TSIG-ALLOW-AXFR'",
"'%s'" % tsigkey['name']])
query = InsertFromSelect(models.DomainMetadata.__table__, query_select)
query_select = select([
models.Domain.__table__.c.id,
"'TSIG-ALLOW-AXFR'",
"'%s'" % tsigkey['name']]
)
columns = [
models.DomainMetadata.__table__.c.domain_id,
models.DomainMetadata.__table__.c.kind,
models.DomainMetadata.__table__.c.content,
]
query = InsertFromSelect(models.DomainMetadata.__table__, query_select,
columns)
# NOTE(kiall): A TX is required for, at the least, SQLite.
self.session.begin()
@ -426,19 +434,28 @@ class PowerDNSBackend(base.Backend):
"existing domains upon server create is: %s"
% ns_rec_content)
query_select = select([null(),
models.Domain.__table__.c.id,
models.Domain.__table__.c.name,
"'NS'",
"'%s'" % ns_rec_content,
null(),
null(),
null(),
null(),
1,
"'%s'" % self._sanitize_uuid_str(server['id']),
1])
query = InsertFromSelect(models.Record.__table__, query_select)
query_select = select([
models.Domain.__table__.c.id,
"'%s'" % self._sanitize_uuid_str(server['id']),
models.Domain.__table__.c.name,
"'NS'",
"'%s'" % ns_rec_content,
1,
1]
)
columns = [
models.Record.__table__.c.domain_id,
models.Record.__table__.c.designate_id,
models.Record.__table__.c.name,
models.Record.__table__.c.type,
models.Record.__table__.c.content,
models.Record.__table__.c.auth,
models.Record.__table__.c.inherit_ttl,
]
query = InsertFromSelect(models.Record.__table__, query_select,
columns)
# Execute the manually prepared query
# A TX is required for, at the least, SQLite.

View File

@ -21,17 +21,35 @@ class InsertFromSelect(Executable, ClauseElement):
execution_options = \
Executable._execution_options.union({'autocommit': True})
def __init__(self, table, select):
def __init__(self, table, select, columns=None):
self.table = table
self.select = select
self.columns = columns
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s %s" % (
compiler.process(element.table, asfrom=True),
compiler.process(element.select)
)
# NOTE(kiall): SQLA 0.8.3+ has an InsertFromSelect built in:
# sqlalchemy.sql.expression.Insert.from_select
# This code can be removed once we require 0.8.3+
table = compiler.process(element.table, asfrom=True)
select = compiler.process(element.select)
if element.columns is not None:
columns = [compiler.preparer.format_column(c) for c in element.columns]
columns = ", ".join(columns)
return "INSERT INTO %s (%s) %s" % (
table,
columns,
select
)
else:
return "INSERT INTO %s %s" % (
table,
select
)
# # Dialect specific compilation example, should it be needed.