summary refs log tree commit diff stats
path: root/lib/noun_query.cpp
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2016-04-15 17:24:44 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2016-04-15 17:24:44 -0400
commit040ee58fecdc9c478004bc2e554e1ae126ec4602 (patch)
tree672a75690952ba8055ab9765ba0a475e056e35d4 /lib/noun_query.cpp
parent3a225f5eb709262b9d44d49519136ea9a2a71000 (diff)
downloadverbly-040ee58fecdc9c478004bc2e554e1ae126ec4602.tar.gz
verbly-040ee58fecdc9c478004bc2e554e1ae126ec4602.tar.bz2
verbly-040ee58fecdc9c478004bc2e554e1ae126ec4602.zip
Added support for ImageNet and fixed bug with query interface
Datafile change: nouns now know how many images are associated with them on ImageNet, and also have their WordNet synset ID saved so that you can query for images of that noun via the ImageNet API. So far, verbly only exposes the ImageNet API URL, and doesn't actually interact with it itself. This may be changed in the future.

The query interface had a huge issue in which multiple instances of the same condition would overwrite each other. This has been fixed.
Diffstat (limited to 'lib/noun_query.cpp')
-rw-r--r--lib/noun_query.cpp274
1 files changed, 135 insertions, 139 deletions
diff --git a/lib/noun_query.cpp b/lib/noun_query.cpp index 83bb47d..19a1297 100644 --- a/lib/noun_query.cpp +++ b/lib/noun_query.cpp
@@ -370,6 +370,21 @@ namespace verbly {
370 370
371 return *this; 371 return *this;
372 } 372 }
373
374 noun_query& noun_query::at_least_n_images(int _arg)
375 {
376 _at_least_n_images = _arg;
377
378 return *this;
379 }
380
381 noun_query& noun_query::with_wnid(int _arg)
382 {
383 _with_wnid.insert(_arg);
384
385 return *this;
386 }
387
373 /* 388 /*
374 noun_query& noun_query::derived_from(const word& _w) 389 noun_query& noun_query::derived_from(const word& _w)
375 { 390 {
@@ -457,8 +472,9 @@ namespace verbly {
457 construct << " "; 472 construct << " ";
458 } 473 }
459 474
460 construct << "SELECT noun_id, singular, plural FROM nouns"; 475 construct << "SELECT noun_id, singular, plural, wnid FROM nouns";
461 std::list<std::string> conditions; 476 std::list<std::string> conditions;
477 std::list<binding> bindings;
462 478
463 if (_has_prn) 479 if (_has_prn)
464 { 480 {
@@ -467,21 +483,32 @@ namespace verbly {
467 483
468 if (!_rhymes.empty()) 484 if (!_rhymes.empty())
469 { 485 {
470 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE @RHMPRN"); 486 std::list<std::string> clauses(_rhymes.size(), "pronunciation LIKE ?");
471 std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; 487 std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
472 conditions.push_back(cond); 488 conditions.push_back(cond);
489
490 for (auto rhyme : _rhymes)
491 {
492 bindings.emplace_back("%" + rhyme);
493 }
473 } 494 }
474 495
475 for (auto except : _except) 496 for (auto except : _except)
476 { 497 {
477 conditions.push_back("noun_id != @EXCID"); 498 conditions.push_back("noun_id != ?");
499 bindings.emplace_back(except._id);
478 } 500 }
479 501
480 if (!_with_singular_form.empty()) 502 if (!_with_singular_form.empty())
481 { 503 {
482 std::list<std::string> clauses(_with_singular_form.size(), "singular = @SFORM"); 504 std::list<std::string> clauses(_with_singular_form.size(), "singular = ?");
483 std::string cond = "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; 505 std::string cond = "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")";
484 conditions.push_back(cond); 506 conditions.push_back(cond);
507
508 for (auto form : _with_singular_form)
509 {
510 bindings.emplace_back(form);
511 }
485 } 512 }
486 513
487 if (!_with_prefix.empty()) 514 if (!_with_prefix.empty())
@@ -491,11 +518,13 @@ namespace verbly {
491 { 518 {
492 case filter<std::string>::type::singleton: 519 case filter<std::string>::type::singleton:
493 { 520 {
521 bindings.emplace_back(f.get_elem() + "%");
522
494 if (notlogic == f.get_notlogic()) 523 if (notlogic == f.get_notlogic())
495 { 524 {
496 return "singular LIKE @PREFIX"; 525 return "singular LIKE ?";
497 } else { 526 } else {
498 return "singular NOT LIKE @PREFIX"; 527 return "singular NOT LIKE ?";
499 } 528 }
500 } 529 }
501 530
@@ -528,11 +557,13 @@ namespace verbly {
528 { 557 {
529 case filter<std::string>::type::singleton: 558 case filter<std::string>::type::singleton:
530 { 559 {
560 bindings.emplace_back("%" + f.get_elem());
561
531 if (notlogic == f.get_notlogic()) 562 if (notlogic == f.get_notlogic())
532 { 563 {
533 return "singular LIKE @SUFFIX"; 564 return "singular LIKE ?";
534 } else { 565 } else {
535 return "singular NOT LIKE @SUFFIX"; 566 return "singular NOT LIKE ?";
536 } 567 }
537 } 568 }
538 569
@@ -560,7 +591,8 @@ namespace verbly {
560 591
561 if (_with_complexity != unlimited) 592 if (_with_complexity != unlimited)
562 { 593 {
563 conditions.push_back("complexity = @COMPLEX"); 594 conditions.push_back("complexity = ?");
595 bindings.emplace_back(_with_complexity);
564 } 596 }
565 597
566 if (_is_hypernym) 598 if (_is_hypernym)
@@ -585,11 +617,13 @@ namespace verbly {
585 { 617 {
586 case filter<noun>::type::singleton: 618 case filter<noun>::type::singleton:
587 { 619 {
620 bindings.emplace_back(f.get_elem()._id);
621
588 if (notlogic == f.get_notlogic()) 622 if (notlogic == f.get_notlogic())
589 { 623 {
590 return "hyponym_id = @HYPO"; 624 return "hyponym_id = ?";
591 } else { 625 } else {
592 return "hyponym_id != @HYPO"; 626 return "hyponym_id != ?";
593 } 627 }
594 } 628 }
595 629
@@ -713,11 +747,13 @@ namespace verbly {
713 { 747 {
714 case filter<noun>::type::singleton: 748 case filter<noun>::type::singleton:
715 { 749 {
750 bindings.emplace_back(f.get_elem()._id);
751
716 if (notlogic == f.get_notlogic()) 752 if (notlogic == f.get_notlogic())
717 { 753 {
718 return "hypernym_id = @HYPER"; 754 return "hypernym_id = ?";
719 } else { 755 } else {
720 return "hypernym_id != @HYPER"; 756 return "hypernym_id != ?";
721 } 757 }
722 } 758 }
723 759
@@ -767,11 +803,13 @@ namespace verbly {
767 { 803 {
768 case filter<noun>::type::singleton: 804 case filter<noun>::type::singleton:
769 { 805 {
806 bindings.emplace_back(f.get_elem()._id);
807
770 if (notlogic == f.get_notlogic()) 808 if (notlogic == f.get_notlogic())
771 { 809 {
772 return "holonym_id = @PHOLO"; 810 return "holonym_id = ?";
773 } else { 811 } else {
774 return "holonym_id != @PHOLO"; 812 return "holonym_id != ?";
775 } 813 }
776 } 814 }
777 815
@@ -858,11 +896,13 @@ namespace verbly {
858 { 896 {
859 case filter<noun>::type::singleton: 897 case filter<noun>::type::singleton:
860 { 898 {
899 bindings.emplace_back(f.get_elem()._id);
900
861 if (notlogic == f.get_notlogic()) 901 if (notlogic == f.get_notlogic())
862 { 902 {
863 return "meronym_id = @PMERO"; 903 return "meronym_id = ?";
864 } else { 904 } else {
865 return "meronym_id != @PMERO"; 905 return "meronym_id != ?";
866 } 906 }
867 } 907 }
868 908
@@ -949,11 +989,13 @@ namespace verbly {
949 { 989 {
950 case filter<noun>::type::singleton: 990 case filter<noun>::type::singleton:
951 { 991 {
992 bindings.emplace_back(f.get_elem()._id);
993
952 if (notlogic == f.get_notlogic()) 994 if (notlogic == f.get_notlogic())
953 { 995 {
954 return "holonym_id = @SHOLO"; 996 return "holonym_id = ?";
955 } else { 997 } else {
956 return "holonym_id != @SHOLO"; 998 return "holonym_id != ?";
957 } 999 }
958 } 1000 }
959 1001
@@ -1040,11 +1082,13 @@ namespace verbly {
1040 { 1082 {
1041 case filter<noun>::type::singleton: 1083 case filter<noun>::type::singleton:
1042 { 1084 {
1085 bindings.emplace_back(f.get_elem()._id);
1086
1043 if (notlogic == f.get_notlogic()) 1087 if (notlogic == f.get_notlogic())
1044 { 1088 {
1045 return "meronym_id = @SMERO"; 1089 return "meronym_id = ?";
1046 } else { 1090 } else {
1047 return "meronym_id != @SMERO"; 1091 return "meronym_id != ?";
1048 } 1092 }
1049 } 1093 }
1050 1094
@@ -1131,11 +1175,13 @@ namespace verbly {
1131 { 1175 {
1132 case filter<noun>::type::singleton: 1176 case filter<noun>::type::singleton:
1133 { 1177 {
1178 bindings.emplace_back(f.get_elem()._id);
1179
1134 if (notlogic == f.get_notlogic()) 1180 if (notlogic == f.get_notlogic())
1135 { 1181 {
1136 return "holonym_id = @MHOLO"; 1182 return "holonym_id = ?";
1137 } else { 1183 } else {
1138 return "holonym_id != @MHOLO"; 1184 return "holonym_id != ?";
1139 } 1185 }
1140 } 1186 }
1141 1187
@@ -1222,11 +1268,13 @@ namespace verbly {
1222 { 1268 {
1223 case filter<noun>::type::singleton: 1269 case filter<noun>::type::singleton:
1224 { 1270 {
1271 bindings.emplace_back(f.get_elem()._id);
1272
1225 if (notlogic == f.get_notlogic()) 1273 if (notlogic == f.get_notlogic())
1226 { 1274 {
1227 return "meronym_id = @MMERO"; 1275 return "meronym_id = ?";
1228 } else { 1276 } else {
1229 return "meronym_id != @MMERO"; 1277 return "meronym_id != ?";
1230 } 1278 }
1231 } 1279 }
1232 1280
@@ -1323,11 +1371,13 @@ namespace verbly {
1323 { 1371 {
1324 case filter<noun>::type::singleton: 1372 case filter<noun>::type::singleton:
1325 { 1373 {
1374 bindings.emplace_back(f.get_elem()._id);
1375
1326 if (notlogic == f.get_notlogic()) 1376 if (notlogic == f.get_notlogic())
1327 { 1377 {
1328 return "class_id = @CLSID"; 1378 return "class_id = ?";
1329 } else { 1379 } else {
1330 return "class_id != @CLSID"; 1380 return "class_id != ?";
1331 } 1381 }
1332 } 1382 }
1333 1383
@@ -1377,11 +1427,13 @@ namespace verbly {
1377 { 1427 {
1378 case filter<noun>::type::singleton: 1428 case filter<noun>::type::singleton:
1379 { 1429 {
1430 bindings.emplace_back(f.get_elem()._id);
1431
1380 if (notlogic == f.get_notlogic()) 1432 if (notlogic == f.get_notlogic())
1381 { 1433 {
1382 return "instance_id = @INSID"; 1434 return "instance_id = ?";
1383 } else { 1435 } else {
1384 return "instance_id != @INSID"; 1436 return "instance_id != ?";
1385 } 1437 }
1386 } 1438 }
1387 1439
@@ -1431,11 +1483,13 @@ namespace verbly {
1431 { 1483 {
1432 case filter<noun>::type::singleton: 1484 case filter<noun>::type::singleton:
1433 { 1485 {
1486 bindings.emplace_back(f.get_elem()._id);
1487
1434 if (notlogic == f.get_notlogic()) 1488 if (notlogic == f.get_notlogic())
1435 { 1489 {
1436 return "noun_1_id = @SYNID"; 1490 return "noun_1_id = ?";
1437 } else { 1491 } else {
1438 return "noun_1_id != @SYNID"; 1492 return "noun_1_id != ?";
1439 } 1493 }
1440 } 1494 }
1441 1495
@@ -1485,11 +1539,13 @@ namespace verbly {
1485 { 1539 {
1486 case filter<noun>::type::singleton: 1540 case filter<noun>::type::singleton:
1487 { 1541 {
1542 bindings.emplace_back(f.get_elem()._id);
1543
1488 if (notlogic == f.get_notlogic()) 1544 if (notlogic == f.get_notlogic())
1489 { 1545 {
1490 return "noun_1_id = @ANTID"; 1546 return "noun_1_id = ?";
1491 } else { 1547 } else {
1492 return "noun_1_id != @ANTID"; 1548 return "noun_1_id != ?";
1493 } 1549 }
1494 } 1550 }
1495 1551
@@ -1539,11 +1595,13 @@ namespace verbly {
1539 { 1595 {
1540 case filter<adjective>::type::singleton: 1596 case filter<adjective>::type::singleton:
1541 { 1597 {
1598 bindings.emplace_back(f.get_elem()._id);
1599
1542 if (notlogic == f.get_notlogic()) 1600 if (notlogic == f.get_notlogic())
1543 { 1601 {
1544 return "pertainym_id = @PERID"; 1602 return "pertainym_id = ?";
1545 } else { 1603 } else {
1546 return "pertainym_id != @PERID"; 1604 return "pertainym_id != ?";
1547 } 1605 }
1548 } 1606 }
1549 1607
@@ -1593,11 +1651,13 @@ namespace verbly {
1593 { 1651 {
1594 case filter<adjective>::type::singleton: 1652 case filter<adjective>::type::singleton:
1595 { 1653 {
1654 bindings.emplace_back(f.get_elem()._id);
1655
1596 if (notlogic == f.get_notlogic()) 1656 if (notlogic == f.get_notlogic())
1597 { 1657 {
1598 return "adjective_id = @VALID"; 1658 return "adjective_id = ?";
1599 } else { 1659 } else {
1600 return "adjective_id != @VALID"; 1660 return "adjective_id != ?";
1601 } 1661 }
1602 } 1662 }
1603 1663
@@ -1624,6 +1684,25 @@ namespace verbly {
1624 cond << ")"; 1684 cond << ")";
1625 conditions.push_back(cond.str()); 1685 conditions.push_back(cond.str());
1626 } 1686 }
1687
1688 if (_at_least_n_images != unlimited)
1689 {
1690 conditions.push_back("images >= ?");
1691 bindings.emplace_back(_at_least_n_images);
1692 }
1693
1694 if (!_with_wnid.empty())
1695 {
1696 std::vector<std::string> clauses(_with_wnid.size(), "wnid = ?");
1697 std::string cond = verbly::implode(std::begin(clauses), std::end(clauses), " OR ");
1698 conditions.push_back("(" + cond + ")");
1699
1700 for (auto wnid : _with_wnid)
1701 {
1702 bindings.emplace_back(wnid);
1703 }
1704 }
1705
1627 /* 1706 /*
1628 if (!_derived_from_adjective.empty()) 1707 if (!_derived_from_adjective.empty())
1629 { 1708 {
@@ -1690,114 +1769,29 @@ namespace verbly {
1690 throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); 1769 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
1691 } 1770 }
1692 1771
1693 if (!_rhymes.empty()) 1772 int i = 1;
1773 for (auto& binding : bindings)
1694 { 1774 {
1695 int i = 0; 1775 switch (binding.get_type())
1696 for (auto rhyme : _rhymes)
1697 { 1776 {
1698 std::string rhymer = "%" + rhyme; 1777 case binding::type::integer:
1699 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@RHMPRN"), rhymer.c_str(), rhymer.length(), SQLITE_STATIC); 1778 {
1779 sqlite3_bind_int(ppstmt, i, binding.get_integer());
1780
1781 break;
1782 }
1700 1783
1701 i++; 1784 case binding::type::string:
1785 {
1786 sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC);
1787
1788 break;
1789 }
1702 } 1790 }
1791
1792 i++;
1703 } 1793 }
1704 1794
1705 for (auto except : _except)
1706 {
1707 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@EXCID"), except._id);
1708 }
1709
1710 for (auto sform : _with_singular_form)
1711 {
1712 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SFORM"), sform.c_str(), sform.size(), SQLITE_STATIC);
1713 }
1714
1715 for (auto prefix : _with_prefix.inorder_flatten())
1716 {
1717 std::string pfat = prefix + "%";
1718 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PREFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC);
1719 }
1720
1721 for (auto suffix : _with_suffix.inorder_flatten())
1722 {
1723 std::string pfat = "%" + suffix;
1724 sqlite3_bind_text(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SUFFIX"), pfat.c_str(), pfat.length(), SQLITE_STATIC);
1725 }
1726
1727 if (_with_complexity != unlimited)
1728 {
1729 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@COMPLEX"), _with_complexity);
1730 }
1731
1732 for (auto hyponym : _hypernym_of.inorder_flatten())
1733 {
1734 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPO"), hyponym._id);
1735 }
1736
1737 for (auto hypernym : _hyponym_of.inorder_flatten())
1738 {
1739 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@HYPER"), hypernym._id);
1740 }
1741
1742 for (auto holonym : _part_meronym_of.inorder_flatten())
1743 {
1744 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PHOLO"), holonym._id);
1745 }
1746
1747 for (auto meronym : _part_holonym_of.inorder_flatten())
1748 {
1749 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PMERO"), meronym._id);
1750 }
1751
1752 for (auto holonym : _substance_meronym_of.inorder_flatten())
1753 {
1754 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SHOLO"), holonym._id);
1755 }
1756
1757 for (auto meronym : _substance_holonym_of.inorder_flatten())
1758 {
1759 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SMERO"), meronym._id);
1760 }
1761
1762 for (auto holonym : _member_meronym_of.inorder_flatten())
1763 {
1764 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MHOLO"), holonym._id);
1765 }
1766
1767 for (auto meronym : _member_holonym_of.inorder_flatten())
1768 {
1769 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@MMERO"), meronym._id);
1770 }
1771
1772 for (auto cls : _instance_of.inorder_flatten())
1773 {
1774 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@CLSID"), cls._id);
1775 }
1776
1777 for (auto inst : _class_of.inorder_flatten())
1778 {
1779 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@INSID"), inst._id);
1780 }
1781
1782 for (auto synonym : _synonym_of.inorder_flatten())
1783 {
1784 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@SYNID"), synonym._id);
1785 }
1786
1787 for (auto antonym : _antonym_of.inorder_flatten())
1788 {
1789 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@ANTID"), antonym._id);
1790 }
1791
1792 for (auto pertainym : _anti_pertainym_of.inorder_flatten())
1793 {
1794 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@PERID"), pertainym._id);
1795 }
1796
1797 for (auto value : _attribute_of.inorder_flatten())
1798 {
1799 sqlite3_bind_int(ppstmt, sqlite3_bind_parameter_index(ppstmt, "@VALID"), value._id);
1800 }
1801 /* 1795 /*
1802 for (auto adj : _derived_from_adjective) 1796 for (auto adj : _derived_from_adjective)
1803 { 1797 {
@@ -1839,6 +1833,8 @@ namespace verbly {
1839 { 1833 {
1840 tnc._plural = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2))); 1834 tnc._plural = std::string(reinterpret_cast<const char*>(sqlite3_column_text(ppstmt, 2)));
1841 } 1835 }
1836
1837 tnc._wnid = sqlite3_column_int(ppstmt, 3);
1842 1838
1843 output.push_back(tnc); 1839 output.push_back(tnc);
1844 } 1840 }