]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Use searchRecords and searchComments in search-data
authorAki Tuomi <cmouse@desteem.org>
Thu, 30 Jul 2015 16:26:11 +0000 (19:26 +0300)
committerAki Tuomi <cmouse@cmouse.fi>
Tue, 4 Aug 2015 12:26:15 +0000 (15:26 +0300)
pdns/ws-auth.cc

index 6a7e72cb401a7fe6c9620ac3f6c9bb8484fa2954..93fac5e1ba57d405a9d245cd310963ecd326ddf5 100644 (file)
@@ -1079,81 +1079,88 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) {
     throw HttpMethodNotAllowedException();
 
   string q = req->getvars["q"];
+  string sMax = req->getvars["max"];
+  int maxEnts = 100;
+  int ents = 0;
+
   if (q.empty())
     throw ApiException("Query q can't be blank");
+  if (sMax.empty() == false)
+    maxEnts = boost::lexical_cast<int>(sMax);
+  if (maxEnts < 1)
+    throw ApiException("Maximum entries must be larger than 0");
 
+  SimpleMatch sm(q,true);
   UeberBackend B;
-
   vector<DomainInfo> domains;
-  B.getAllDomains(&domains, true); // incl. disabled
-
+  vector<DNSResourceRecord> result_rr;
+  vector<Comment> result_c;
+  map<int,DNSName> zoneIdZone;
+  map<int,DNSName>::iterator val;
   Document doc;
-  doc.SetArray();
 
-  DNSResourceRecord rr;
-  Comment comment;
+  doc.SetArray();
 
-  BOOST_FOREACH(const DomainInfo& di, domains) {
-    string zoneId = apiZoneNameToId(di.zone.toString());
+  B.getAllDomains(&domains, true);
 
-    if (pdns_ci_find(di.zone.toString(), q) != string::npos) {
+  for(const DomainInfo di: domains)
+  {   
+    if (ents < maxEnts && sm.match(di.zone)) {
       Value object;
       object.SetObject();
-      object.AddMember("type", "zone", doc.GetAllocator());
-      Value jzoneId(zoneId.c_str(), doc.GetAllocator()); // copy
-      object.AddMember("zone_id", jzoneId, doc.GetAllocator());
+      object.AddMember("object_type", "zone", doc.GetAllocator());
+      object.AddMember("zone_id", di.id, doc.GetAllocator());
       Value jzoneName(di.zone.toString().c_str(), doc.GetAllocator()); // copy
       object.AddMember("name", jzoneName, doc.GetAllocator());
       doc.PushBack(object, doc.GetAllocator());
+      ents++;
     }
+    zoneIdZone[di.id] = di.zone; // populate cache
+  }
 
-    // if zone name is an exact match, don't bother with returning all records/comments in it
-    if (di.zone == q) {
-      continue;
-    }
-    // the code below is too slow
-#if 0
-    di.backend->list(di.zone, di.id, true); // incl. disabled
-    while(di.backend->get(rr)) {
-      if (!rr.qtype.getCode())
-        continue; // skip empty non-terminals
-
-      if (pdns_ci_find(rr.qname, q) == string::npos && pdns_ci_find(rr.content, q) == string::npos)
-        continue;
-
+  if (B.searchRecords(q, maxEnts, result_rr))
+  {
+    for(const DNSResourceRecord& rr: result_rr)
+    {
       Value object;
       object.SetObject();
-      object.AddMember("type", "record", doc.GetAllocator());
-      Value jzoneId(zoneId.c_str(), doc.GetAllocator()); // copy
-      object.AddMember("zone_id", jzoneId, doc.GetAllocator());
-      Value jzoneName(di.zone.c_str(), doc.GetAllocator()); // copy
-      object.AddMember("zone_name", jzoneName, doc.GetAllocator());
-      Value jname(rr.qname.c_str(), doc.GetAllocator()); // copy
+      object.AddMember("object_type", "record", doc.GetAllocator());
+      object.AddMember("zone_id", rr.domain_id, doc.GetAllocator());
+      if ((val = zoneIdZone.find(rr.domain_id)) != zoneIdZone.end()) {
+        Value zname(val->second.toString().c_str(), doc.GetAllocator()); // copy
+        object.AddMember("zone", zname, doc.GetAllocator()); // copy
+      }
+      Value jname(rr.qname.toString().c_str(), doc.GetAllocator()); // copy
       object.AddMember("name", jname, doc.GetAllocator());
+      Value jtype(rr.qtype.getName().c_str(), doc.GetAllocator()); // copy
+      object.AddMember("type", jtype, doc.GetAllocator());
+      object.AddMember("ttl", rr.ttl, doc.GetAllocator());
+      object.AddMember("disabled", rr.disabled, doc.GetAllocator());
       Value jcontent(rr.content.c_str(), doc.GetAllocator()); // copy
       object.AddMember("content", jcontent, doc.GetAllocator());
       doc.PushBack(object, doc.GetAllocator());
     }
+  }
 
-    di.backend->listComments(di.id);
-    while(di.backend->getComment(comment)) {
-      if (pdns_ci_find(comment.qname, q) == string::npos && pdns_ci_find(comment.content, q) == string::npos)
-        continue;
+  if (B.searchComments(q, maxEnts, result_c))
+  {
+    for(const Comment &c: result_c)
+    {
 
       Value object;
       object.SetObject();
-      object.AddMember("type", "comment", doc.GetAllocator());
-      Value jzoneId(zoneId.c_str(), doc.GetAllocator()); // copy
-      object.AddMember("zone_id", jzoneId, doc.GetAllocator());
-      Value jzoneName(di.zone.c_str(), doc.GetAllocator()); // copy
-      object.AddMember("zone_name", jzoneName, doc.GetAllocator());
-      Value jname(comment.qname.c_str(), doc.GetAllocator()); // copy
+      object.AddMember("object_type", "comment", doc.GetAllocator());
+      object.AddMember("zone_id", c.domain_id, doc.GetAllocator());
+      if ((val = zoneIdZone.find(c.domain_id)) != zoneIdZone.end()) {
+        Value zname(val->second.toString().c_str(), doc.GetAllocator()); // copy
+        object.AddMember("zone", zname, doc.GetAllocator()); // copy
+      }
+      Value jname(c.qname.c_str(), doc.GetAllocator()); // copy
       object.AddMember("name", jname, doc.GetAllocator());
-      Value jcontent(comment.content.c_str(), doc.GetAllocator()); // copy
+      Value jcontent(c.content.c_str(), doc.GetAllocator()); // copy
       object.AddMember("content", jcontent, doc.GetAllocator());
       doc.PushBack(object, doc.GetAllocator());
     }
-#endif
   }
 
   resp->setBody(doc);