comparison Framework/Plugins/IndexBackend.cpp @ 75:52c70007bb87 db-changes

new extension implemented for PostgreSQL: SetResourcesContent
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 05 Jan 2019 11:41:15 +0100
parents a4e440e65c68
children a1c6238b26f8
comparison
equal deleted inserted replaced
74:a4e440e65c68 75:52c70007bb87
703 "SELECT CAST(COUNT(*) AS UNSIGNED INT) FROM Resources WHERE resourceType=${type}")); 703 "SELECT CAST(COUNT(*) AS UNSIGNED INT) FROM Resources WHERE resourceType=${type}"));
704 break; 704 break;
705 705
706 case Dialect_PostgreSQL: 706 case Dialect_PostgreSQL:
707 statement.reset(new DatabaseManager::CachedStatement( 707 statement.reset(new DatabaseManager::CachedStatement(
708 STATEMENT_FROM_HERE, GetManager(), 708 STATEMENT_FROM_HERE, GetManager(),
709 "SELECT CAST(COUNT(*) AS BIGINT) FROM Resources WHERE resourceType=${type}")); 709 "SELECT CAST(COUNT(*) AS BIGINT) FROM Resources WHERE resourceType=${type}"));
710 break; 710 break;
711 711
712 case Dialect_SQLite: 712 case Dialect_SQLite:
713 statement.reset(new DatabaseManager::CachedStatement( 713 statement.reset(new DatabaseManager::CachedStatement(
714 STATEMENT_FROM_HERE, GetManager(), 714 STATEMENT_FROM_HERE, GetManager(),
715 "SELECT COUNT(*) FROM Resources WHERE resourceType=${type}")); 715 "SELECT COUNT(*) FROM Resources WHERE resourceType=${type}"));
716 break; 716 break;
717 717
718 default: 718 default:
719 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 719 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
720 } 720 }
1717 1717
1718 statement.Next(); 1718 statement.Next();
1719 } 1719 }
1720 } 1720 }
1721 #endif 1721 #endif
1722
1723
1724 #if ORTHANC_PLUGINS_HAS_DATABASE_OPTIMIZATIONS_1 == 1
1725 static void ExecuteSetResourcesContentTags(
1726 DatabaseManager& manager,
1727 const std::string& table,
1728 const std::string& variablePrefix,
1729 uint32_t count,
1730 const OrthancPluginResourcesContentTags* tags)
1731 {
1732 std::string sql;
1733 Dictionary args;
1734
1735 for (uint32_t i = 0; i < count; i++)
1736 {
1737 std::string name = variablePrefix + boost::lexical_cast<std::string>(i);
1738
1739 args.SetUtf8Value(name, tags[i].value);
1740
1741 std::string insert = ("(" + boost::lexical_cast<std::string>(tags[i].resource) + ", " +
1742 boost::lexical_cast<std::string>(tags[i].group) + ", " +
1743 boost::lexical_cast<std::string>(tags[i].element) + ", " +
1744 "${" + name + "})");
1745
1746 if (sql.empty())
1747 {
1748 sql = "INSERT INTO " + table + " VALUES " + insert;
1749 }
1750 else
1751 {
1752 sql += ", " + insert;
1753 }
1754 }
1755
1756 if (!sql.empty())
1757 {
1758 DatabaseManager::StandaloneStatement statement(manager, sql);
1759
1760 for (uint32_t i = 0; i < count; i++)
1761 {
1762 statement.SetParameterType(variablePrefix + boost::lexical_cast<std::string>(i),
1763 ValueType_Utf8String);
1764 }
1765
1766 statement.Execute(args);
1767 }
1768 }
1769 #endif
1770
1771
1772 #if ORTHANC_PLUGINS_HAS_DATABASE_OPTIMIZATIONS_1 == 1
1773 static void ExecuteSetResourcesContentMetadata(
1774 DatabaseManager& manager,
1775 uint32_t count,
1776 const OrthancPluginResourcesContentMetadata* metadata)
1777 {
1778 std::string sqlRemove; // To overwrite
1779 std::string sqlInsert;
1780 Dictionary args;
1781
1782 for (uint32_t i = 0; i < count; i++)
1783 {
1784 std::string name = "m" + boost::lexical_cast<std::string>(i);
1785
1786 args.SetUtf8Value(name, metadata[i].value);
1787
1788 std::string insert = ("(" + boost::lexical_cast<std::string>(metadata[i].resource) + ", " +
1789 boost::lexical_cast<std::string>(metadata[i].metadata) + ", " +
1790 "${" + name + "})");
1791
1792 std::string remove = ("(id=" + boost::lexical_cast<std::string>(metadata[i].resource) +
1793 " AND type=" + boost::lexical_cast<std::string>(metadata[i].metadata)
1794 + ")");
1795
1796 if (sqlInsert.empty())
1797 {
1798 sqlInsert = "INSERT INTO Metadata VALUES " + insert;
1799 }
1800 else
1801 {
1802 sqlInsert += ", " + insert;
1803 }
1804
1805 if (sqlRemove.empty())
1806 {
1807 sqlRemove = "DELETE FROM Metadata WHERE " + remove;
1808 }
1809 else
1810 {
1811 sqlRemove += " OR " + remove;
1812 }
1813 }
1814
1815 if (!sqlRemove.empty())
1816 {
1817 DatabaseManager::StandaloneStatement statement(manager, sqlRemove);
1818 statement.Execute();
1819 }
1820
1821 if (!sqlInsert.empty())
1822 {
1823 DatabaseManager::StandaloneStatement statement(manager, sqlInsert);
1824
1825 for (uint32_t i = 0; i < count; i++)
1826 {
1827 statement.SetParameterType("m" + boost::lexical_cast<std::string>(i),
1828 ValueType_Utf8String);
1829 }
1830
1831 statement.Execute(args);
1832 }
1833 }
1834 #endif
1835
1836
1837 #if ORTHANC_PLUGINS_HAS_DATABASE_OPTIMIZATIONS_1 == 1
1838 // New primitive since Orthanc 1.5.2
1839 void IndexBackend::SetResourcesContent(
1840 uint32_t countIdentifierTags,
1841 const OrthancPluginResourcesContentTags* identifierTags,
1842 uint32_t countMainDicomTags,
1843 const OrthancPluginResourcesContentTags* mainDicomTags,
1844 uint32_t countMetadata,
1845 const OrthancPluginResourcesContentMetadata* metadata)
1846 {
1847 /**
1848 * TODO - PostgreSQL doesn't allow multiple commands in a prepared
1849 * statement, so we execute 3 separate commands (for identifiers,
1850 * main tags and metadata). Maybe MySQL does not suffer from the
1851 * same limitation, to check.
1852 **/
1853
1854 ExecuteSetResourcesContentTags(GetManager(), "DicomIdentifiers", "i",
1855 countIdentifierTags, identifierTags);
1856
1857 ExecuteSetResourcesContentTags(GetManager(), "MainDicomTags", "t",
1858 countMainDicomTags, mainDicomTags);
1859
1860 ExecuteSetResourcesContentMetadata(GetManager(), countMetadata, metadata);
1861 }
1862 #endif
1722 } 1863 }