int d_residx;
};
-SMySQL::SMySQL(const string &database, const string &host, uint16_t port, const string &msocket, const string &user,
- const string &password, const string &group, bool setIsolation, unsigned int timeout)
+void SMySQL::connect()
{
int retry=1;
#endif
#if MYSQL_VERSION_ID >= 50100
- if(timeout) {
- mysql_options(&d_db, MYSQL_OPT_READ_TIMEOUT, &timeout);
- mysql_options(&d_db, MYSQL_OPT_WRITE_TIMEOUT, &timeout);
+ if(d_timeout) {
+ mysql_options(&d_db, MYSQL_OPT_READ_TIMEOUT, &d_timeout);
+ mysql_options(&d_db, MYSQL_OPT_WRITE_TIMEOUT, &d_timeout);
}
#endif
mysql_options(&d_db, MYSQL_SET_CHARSET_NAME, MYSQL_AUTODETECT_CHARSET_NAME);
#endif
- if (setIsolation && (retry == 1))
+ if (d_setIsolation && (retry == 1))
mysql_options(&d_db, MYSQL_INIT_COMMAND,"SET SESSION tx_isolation='READ-COMMITTED'");
- mysql_options(&d_db, MYSQL_READ_DEFAULT_GROUP, group.c_str());
+ mysql_options(&d_db, MYSQL_READ_DEFAULT_GROUP, d_group.c_str());
- if (!mysql_real_connect(&d_db, host.empty() ? NULL : host.c_str(),
- user.empty() ? NULL : user.c_str(),
- password.empty() ? NULL : password.c_str(),
- database.empty() ? NULL : database.c_str(),
- port,
- msocket.empty() ? NULL : msocket.c_str(),
- CLIENT_MULTI_RESULTS)) {
+ if (!mysql_real_connect(&d_db, d_host.empty() ? NULL : d_host.c_str(),
+ d_user.empty() ? NULL : d_user.c_str(),
+ d_password.empty() ? NULL : d_password.c_str(),
+ d_database.empty() ? NULL : d_database.c_str(),
+ d_port,
+ d_msocket.empty() ? NULL : d_msocket.c_str(),
+ CLIENT_MULTI_RESULTS)) {
if (retry == 0)
throw sPerrorException("Unable to connect to database");
} while (retry >= 0);
}
+SMySQL::SMySQL(const string &database, const string &host, uint16_t port, const string &msocket, const string &user,
+ const string &password, const string &group, bool setIsolation, unsigned int timeout):
+ d_database(database), d_host(host), d_msocket(msocket), d_user(user), d_password(password), d_group(group), d_timeout(timeout), d_port(port), d_setIsolation(setIsolation)
+{
+ connect();
+}
+
void SMySQL::setLog(bool state)
{
s_dolog=state;
void SMySQL::rollback() {
execute("rollback");
}
+
+bool SMySQL::isConnectionUsable()
+{
+ bool usable = false;
+ int sd = d_db.net.fd;
+ bool wasNonBlocking = isNonBlocking(sd);
+
+ if (!wasNonBlocking) {
+ if (!setNonBlocking(sd)) {
+ return usable;
+ }
+ }
+
+ usable = isTCPSocketUsable(sd);
+
+ if (!wasNonBlocking) {
+ if (!setBlocking(sd)) {
+ usable = false;
+ }
+ }
+
+ return usable;
+}
void GSQLBackend::setNotified(uint32_t domain_id, uint32_t serial)
{
try {
+ reconnectIfNeeded();
+
d_UpdateSerialOfZoneQuery_stmt->
bind("serial", serial)->
bind("domain_id", domain_id)->
void GSQLBackend::setFresh(uint32_t domain_id)
{
try {
+ reconnectIfNeeded();
+
d_UpdateLastCheckofZoneQuery_stmt->
bind("last_check", time(0))->
bind("domain_id", domain_id)->
bool GSQLBackend::isMaster(const DNSName &domain, const string &ip)
{
try {
+ reconnectIfNeeded();
+
d_MasterOfDomainsZoneQuery_stmt->
bind("domain", domain)->
execute()->
bool GSQLBackend::setMaster(const DNSName &domain, const string &ip)
{
try {
+ reconnectIfNeeded();
+
d_UpdateMasterOfZoneQuery_stmt->
bind("master", ip)->
bind("domain", domain)->
bool GSQLBackend::setKind(const DNSName &domain, const DomainInfo::DomainKind kind)
{
try {
+ reconnectIfNeeded();
+
d_UpdateKindOfZoneQuery_stmt->
bind("kind", toUpper(DomainInfo::getKindString(kind)))->
bind("domain", domain)->
bool GSQLBackend::setAccount(const DNSName &domain, const string &account)
{
try {
+ reconnectIfNeeded();
+
d_UpdateAccountOfZoneQuery_stmt->
bind("account", account)->
bind("domain", domain)->
/* fill DomainInfo from database info:
id,name,master IP(s),last_check,notified_serial,type,account */
try {
+ reconnectIfNeeded();
+
d_InfoOfDomainsZoneQuery_stmt->
bind("domain", domain)->
execute()->
/* list all domains that need refreshing for which we are slave, and insert into SlaveDomain:
id,name,master IP,serial */
try {
+ reconnectIfNeeded();
+
d_InfoOfAllSlaveDomainsQuery_stmt->
execute()->
getResult(d_result)->
/* list all domains that need notifications for which we are master, and insert into updatedDomains
id,name,master IP,serial */
try {
+ reconnectIfNeeded();
+
d_InfoOfAllMasterDomainsQuery_stmt->
execute()->
getResult(d_result)->
if (!ordername.empty()) {
if (qtype == QType::ANY) {
try {
+ reconnectIfNeeded();
+
d_updateOrderNameAndAuthQuery_stmt->
bind("ordername", ordername.labelReverse().toString(" ", false))->
bind("auth", auth)->
}
} else {
try {
+ reconnectIfNeeded();
+
d_updateOrderNameAndAuthTypeQuery_stmt->
bind("ordername", ordername.labelReverse().toString(" ", false))->
bind("auth", auth)->
}
} else {
if (qtype == QType::ANY) {
+ reconnectIfNeeded();
+
try {
d_nullifyOrderNameAndUpdateAuthQuery_stmt->
bind("auth", auth)->
}
} else {
try {
+ reconnectIfNeeded();
+
d_nullifyOrderNameAndUpdateAuthTypeQuery_stmt->
bind("auth", auth)->
bind("domain_id", domain_id)->
{
if(remove) {
try {
+ reconnectIfNeeded();
+
d_RemoveEmptyNonTerminalsFromZoneQuery_stmt->
bind("domain_id", domain_id)->
execute()->
{
for(const auto& qname: erase) {
try {
+ reconnectIfNeeded();
+
d_DeleteEmptyNonTerminalQuery_stmt->
bind("domain_id", domain_id)->
bind("qname", qname)->
for(const auto& qname: insert) {
try {
+ reconnectIfNeeded();
+
d_InsertEmptyNonTerminalOrderQuery_stmt->
bind("domain_id", domain_id)->
bind("qname", qname)->
SSqlStatement::row_t row;
try {
+ reconnectIfNeeded();
+
d_afterOrderQuery_stmt->
bind("ordername", qname.labelReverse().toString(" ", false))->
bind("domain_id", id)->
if(after.empty()) {
try {
+ reconnectIfNeeded();
+
d_firstOrderQuery_stmt->
bind("domain_id", id)->
execute();
unhashed.clear();
try {
+ reconnectIfNeeded();
+
d_beforeOrderQuery_stmt->
bind("ordername", qname.labelReverse().toString(" ", false))->
bind("domain_id", id)->
}
try {
+ reconnectIfNeeded();
+
d_lastOrderQuery_stmt->
bind("domain_id", id)->
execute();
return false;
try {
+ reconnectIfNeeded();
+
d_AddDomainKeyQuery_stmt->
bind("flags", key.flags)->
bind("active", key.active)->
}
try {
+ reconnectIfNeeded();
+
d_GetLastInsertedKeyIdQuery_stmt->execute();
if (!d_GetLastInsertedKeyIdQuery_stmt->hasNextRow()) {
id = -2;
return false;
try {
+ reconnectIfNeeded();
+
d_ActivateDomainKeyQuery_stmt->
bind("domain", name)->
bind("key_id", id)->
return false;
try {
+ reconnectIfNeeded();
+
d_DeactivateDomainKeyQuery_stmt->
bind("domain", name)->
bind("key_id", id)->
return false;
try {
+ reconnectIfNeeded();
+
d_RemoveDomainKeyQuery_stmt->
bind("domain", name)->
bind("key_id", id)->
bool GSQLBackend::getTSIGKey(const DNSName& name, DNSName* algorithm, string* content)
{
try {
+ reconnectIfNeeded();
+
d_getTSIGKeyQuery_stmt->
bind("key_name", name)->
execute();
bool GSQLBackend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content)
{
try {
+ reconnectIfNeeded();
+
d_setTSIGKeyQuery_stmt->
bind("key_name", name)->
bind("algorithm", algorithm)->
bool GSQLBackend::deleteTSIGKey(const DNSName& name)
{
try {
+ reconnectIfNeeded();
+
d_deleteTSIGKeyQuery_stmt->
bind("key_name", name)->
execute()->
bool GSQLBackend::getTSIGKeys(std::vector< struct TSIGKey > &keys)
{
try {
+ reconnectIfNeeded();
+
d_getTSIGKeysQuery_stmt->
execute();
return false;
try {
+ reconnectIfNeeded();
+
d_ListDomainKeysQuery_stmt->
bind("domain", name)->
execute();
bool GSQLBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta)
{
try {
+ reconnectIfNeeded();
+
d_GetAllDomainMetadataQuery_stmt->
bind("domain", name)->
execute();
return false;
try {
+ reconnectIfNeeded();
+
d_GetDomainMetadataQuery_stmt->
bind("domain", name)->
bind("kind", kind)->
return false;
try {
+ reconnectIfNeeded();
+
d_ClearDomainMetadataQuery_stmt->
bind("domain", name)->
bind("kind", kind)->
void GSQLBackend::lookup(const QType &qtype,const DNSName &qname, DNSPacket *pkt_p, int domain_id)
{
try {
+ reconnectIfNeeded();
+
if(qtype.getCode()!=QType::ANY) {
if(domain_id < 0) {
d_query_name = "basic-query";
DLOG(L<<"GSQLBackend constructing handle for list of domain id '"<<domain_id<<"'"<<endl);
try {
+ reconnectIfNeeded();
+
d_query_name = "list-query";
d_query_stmt = d_listQuery_stmt;
d_query_stmt->
string wildzone = "%." + toLower(zone.toStringNoDot());
try {
+ reconnectIfNeeded();
+
d_query_name = "list-subzone-query";
d_query_stmt = d_listSubZoneQuery_stmt;
d_query_stmt->
// check if we know the ip/ns couple in the database
for(vector<DNSResourceRecord>::const_iterator i=nsset.begin();i!=nsset.end();++i) {
try {
+ reconnectIfNeeded();
+
d_SuperMasterInfoQuery_stmt->
bind("ip", ip)->
bind("nameserver", i->content)->
bool GSQLBackend::createDomain(const DNSName &domain, const string &type, const string &masters, const string &account)
{
try {
+ reconnectIfNeeded();
+
d_InsertZoneQuery_stmt->
bind("type", type)->
bind("domain", domain)->
try {
if (!nameserver.empty()) {
// figure out all IP addresses for the master
+ reconnectIfNeeded();
+
d_GetSuperMasterIPs_stmt->
bind("nameserver", nameserver)->
bind("account", account)->
}
try {
+ reconnectIfNeeded();
+
d_DeleteZoneQuery_stmt->
bind("domain_id", di.id)->
execute()->
DLOG(L<<"GSQLBackend retrieving all domains."<<endl);
try {
+ reconnectIfNeeded();
+
d_getAllDomainsQuery_stmt->
bind("include_disabled", (int)include_disabled)->
execute();
bool GSQLBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<DNSResourceRecord>& rrset)
{
try {
+ reconnectIfNeeded();
+
if (qt != QType::ANY) {
d_DeleteRRSetQuery_stmt->
bind("domain_id", domain_id)->
if (rrset.empty()) {
try {
+ reconnectIfNeeded();
+
d_DeleteCommentRRsetQuery_stmt->
bind("domain_id", domain_id)->
bind("qname", qname)->
}
try {
+ reconnectIfNeeded();
+
d_InsertRecordQuery_stmt->
bind("content",content)->
bind("ttl",r.ttl)->
{
for(const auto& nt: nonterm) {
try {
+ reconnectIfNeeded();
+
d_InsertEmptyNonTerminalOrderQuery_stmt->
bind("domain_id",domain_id)->
bind("qname", nt.first)->
for(const auto& nt: nonterm) {
try {
+ reconnectIfNeeded();
+
d_InsertEmptyNonTerminalOrderQuery_stmt->
bind("domain_id",domain_id)->
bind("qname", nt.first);
bool GSQLBackend::startTransaction(const DNSName &domain, int domain_id)
{
try {
+ reconnectIfNeeded();
+
d_db->startTransaction();
if(domain_id >= 0) {
d_DeleteZoneQuery_stmt->
}
try {
+ reconnectIfNeeded();
+
d_ZoneLastChangeQuery_stmt->
bind("domain_id", sd.domain_id)->
execute()->
bool GSQLBackend::listComments(const uint32_t domain_id)
{
try {
+ reconnectIfNeeded();
+
d_query_name = "list-comments-query";
d_query_stmt = d_ListCommentsQuery_stmt;
d_query_stmt->
void GSQLBackend::feedComment(const Comment& comment)
{
try {
+ reconnectIfNeeded();
+
d_InsertCommentQuery_stmt->
bind("domain_id",comment.domain_id)->
bind("qname",comment.qname)->
bool GSQLBackend::replaceComments(const uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<Comment>& comments)
{
try {
+ reconnectIfNeeded();
+
d_DeleteCommentRRsetQuery_stmt->
bind("domain_id",domain_id)->
bind("qname", qname)->
unique_ptr<SSqlStatement> stmt(d_db->prepare(query,0));
+ reconnectIfNeeded();
+
stmt->execute();
SSqlStatement::row_t row;
try {
string escaped_pattern = pattern2SQLPattern(pattern);
+ reconnectIfNeeded();
+
d_SearchRecordsQuery_stmt->
bind("value", escaped_pattern)->
bind("value2", escaped_pattern)->
try {
string escaped_pattern = pattern2SQLPattern(pattern);
+ reconnectIfNeeded();
+
d_SearchCommentsQuery_stmt->
bind("value", escaped_pattern)->
bind("value2", escaped_pattern)->