outhad-integrations 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +43 -0
  4. data/.ruby-version +1 -0
  5. data/.vscode/settings.json +5 -0
  6. data/README.md +76 -0
  7. data/Rakefile +12 -0
  8. data/lib/outhad/integrations/config.rb +14 -0
  9. data/lib/outhad/integrations/core/base_connector.rb +79 -0
  10. data/lib/outhad/integrations/core/constants.rb +103 -0
  11. data/lib/outhad/integrations/core/destination_connector.rb +20 -0
  12. data/lib/outhad/integrations/core/fullrefresher.rb +19 -0
  13. data/lib/outhad/integrations/core/http_client.rb +17 -0
  14. data/lib/outhad/integrations/core/http_helper.rb +36 -0
  15. data/lib/outhad/integrations/core/query_builder.rb +33 -0
  16. data/lib/outhad/integrations/core/rate_limiter.rb +19 -0
  17. data/lib/outhad/integrations/core/source_connector.rb +66 -0
  18. data/lib/outhad/integrations/core/streaming_http_client.rb +21 -0
  19. data/lib/outhad/integrations/core/unstructured_source_connector.rb +52 -0
  20. data/lib/outhad/integrations/core/utils.rb +123 -0
  21. data/lib/outhad/integrations/core/vector_source_connector.rb +14 -0
  22. data/lib/outhad/integrations/destination/airtable/client.rb +157 -0
  23. data/lib/outhad/integrations/destination/airtable/config/catalog.json +6 -0
  24. data/lib/outhad/integrations/destination/airtable/config/meta.json +15 -0
  25. data/lib/outhad/integrations/destination/airtable/config/spec.json +23 -0
  26. data/lib/outhad/integrations/destination/airtable/icon.svg +6 -0
  27. data/lib/outhad/integrations/destination/airtable/schema_helper.rb +141 -0
  28. data/lib/outhad/integrations/destination/ais_data_store/client.rb +130 -0
  29. data/lib/outhad/integrations/destination/ais_data_store/config/meta.json +15 -0
  30. data/lib/outhad/integrations/destination/ais_data_store/config/spec.json +68 -0
  31. data/lib/outhad/integrations/destination/ais_data_store/icon.svg +4 -0
  32. data/lib/outhad/integrations/destination/amazon_s3/client.rb +92 -0
  33. data/lib/outhad/integrations/destination/amazon_s3/config/catalog.json +16 -0
  34. data/lib/outhad/integrations/destination/amazon_s3/config/meta.json +15 -0
  35. data/lib/outhad/integrations/destination/amazon_s3/config/spec.json +56 -0
  36. data/lib/outhad/integrations/destination/amazon_s3/icon.svg +34 -0
  37. data/lib/outhad/integrations/destination/databricks_lakehouse/client.rb +147 -0
  38. data/lib/outhad/integrations/destination/databricks_lakehouse/config/meta.json +15 -0
  39. data/lib/outhad/integrations/destination/databricks_lakehouse/config/spec.json +44 -0
  40. data/lib/outhad/integrations/destination/databricks_lakehouse/icon.svg +65 -0
  41. data/lib/outhad/integrations/destination/facebook_custom_audience/client.rb +125 -0
  42. data/lib/outhad/integrations/destination/facebook_custom_audience/config/catalog.json +42 -0
  43. data/lib/outhad/integrations/destination/facebook_custom_audience/config/meta.json +15 -0
  44. data/lib/outhad/integrations/destination/facebook_custom_audience/config/spec.json +28 -0
  45. data/lib/outhad/integrations/destination/facebook_custom_audience/icon.svg +23 -0
  46. data/lib/outhad/integrations/destination/google_sheets/client.rb +240 -0
  47. data/lib/outhad/integrations/destination/google_sheets/config/catalog.json +6 -0
  48. data/lib/outhad/integrations/destination/google_sheets/config/meta.json +15 -0
  49. data/lib/outhad/integrations/destination/google_sheets/config/spec.json +75 -0
  50. data/lib/outhad/integrations/destination/google_sheets/icon.svg +1 -0
  51. data/lib/outhad/integrations/destination/http/client.rb +106 -0
  52. data/lib/outhad/integrations/destination/http/config/catalog.json +16 -0
  53. data/lib/outhad/integrations/destination/http/config/meta.json +15 -0
  54. data/lib/outhad/integrations/destination/http/config/spec.json +24 -0
  55. data/lib/outhad/integrations/destination/http/icon.svg +9 -0
  56. data/lib/outhad/integrations/destination/hubspot/client.rb +122 -0
  57. data/lib/outhad/integrations/destination/hubspot/config/catalog.json +351 -0
  58. data/lib/outhad/integrations/destination/hubspot/config/meta.json +15 -0
  59. data/lib/outhad/integrations/destination/hubspot/config/spec.json +18 -0
  60. data/lib/outhad/integrations/destination/hubspot/icon.svg +5 -0
  61. data/lib/outhad/integrations/destination/iterable/client.rb +111 -0
  62. data/lib/outhad/integrations/destination/iterable/config/catalog.json +47 -0
  63. data/lib/outhad/integrations/destination/iterable/config/meta.json +15 -0
  64. data/lib/outhad/integrations/destination/iterable/config/spec.json +19 -0
  65. data/lib/outhad/integrations/destination/iterable/icon.svg +71 -0
  66. data/lib/outhad/integrations/destination/klaviyo/client.rb +119 -0
  67. data/lib/outhad/integrations/destination/klaviyo/config/catalog.json +103 -0
  68. data/lib/outhad/integrations/destination/klaviyo/config/meta.json +15 -0
  69. data/lib/outhad/integrations/destination/klaviyo/config/spec.json +24 -0
  70. data/lib/outhad/integrations/destination/klaviyo/icon.svg +6 -0
  71. data/lib/outhad/integrations/destination/mailchimp/client.rb +141 -0
  72. data/lib/outhad/integrations/destination/mailchimp/config/catalog.json +142 -0
  73. data/lib/outhad/integrations/destination/mailchimp/config/meta.json +15 -0
  74. data/lib/outhad/integrations/destination/mailchimp/config/spec.json +28 -0
  75. data/lib/outhad/integrations/destination/mailchimp/icon.svg +4 -0
  76. data/lib/outhad/integrations/destination/maria_db/client.rb +114 -0
  77. data/lib/outhad/integrations/destination/maria_db/config/meta.json +15 -0
  78. data/lib/outhad/integrations/destination/maria_db/config/spec.json +48 -0
  79. data/lib/outhad/integrations/destination/maria_db/icon.svg +15 -0
  80. data/lib/outhad/integrations/destination/microsoft_dynamics/client.rb +150 -0
  81. data/lib/outhad/integrations/destination/microsoft_dynamics/config/catalog.json +161 -0
  82. data/lib/outhad/integrations/destination/microsoft_dynamics/config/meta.json +15 -0
  83. data/lib/outhad/integrations/destination/microsoft_dynamics/config/spec.json +35 -0
  84. data/lib/outhad/integrations/destination/microsoft_dynamics/icon.svg +2 -0
  85. data/lib/outhad/integrations/destination/microsoft_excel/client.rb +198 -0
  86. data/lib/outhad/integrations/destination/microsoft_excel/config/catalog.json +7 -0
  87. data/lib/outhad/integrations/destination/microsoft_excel/config/meta.json +15 -0
  88. data/lib/outhad/integrations/destination/microsoft_excel/config/spec.json +19 -0
  89. data/lib/outhad/integrations/destination/microsoft_excel/icon.svg +18 -0
  90. data/lib/outhad/integrations/destination/microsoft_sql/client.rb +137 -0
  91. data/lib/outhad/integrations/destination/microsoft_sql/config/meta.json +15 -0
  92. data/lib/outhad/integrations/destination/microsoft_sql/config/spec.json +68 -0
  93. data/lib/outhad/integrations/destination/microsoft_sql/icon.svg +22 -0
  94. data/lib/outhad/integrations/destination/odoo/client.rb +109 -0
  95. data/lib/outhad/integrations/destination/odoo/config/meta.json +15 -0
  96. data/lib/outhad/integrations/destination/odoo/config/spec.json +39 -0
  97. data/lib/outhad/integrations/destination/odoo/icon.svg +21 -0
  98. data/lib/outhad/integrations/destination/oracle_db/client.rb +112 -0
  99. data/lib/outhad/integrations/destination/oracle_db/config/meta.json +15 -0
  100. data/lib/outhad/integrations/destination/oracle_db/config/spec.json +47 -0
  101. data/lib/outhad/integrations/destination/oracle_db/icon.svg +4 -0
  102. data/lib/outhad/integrations/destination/pinecone_db/client.rb +154 -0
  103. data/lib/outhad/integrations/destination/pinecone_db/config/meta.json +15 -0
  104. data/lib/outhad/integrations/destination/pinecone_db/config/spec.json +32 -0
  105. data/lib/outhad/integrations/destination/pinecone_db/icon.svg +1 -0
  106. data/lib/outhad/integrations/destination/postgresql/client.rb +130 -0
  107. data/lib/outhad/integrations/destination/postgresql/config/meta.json +15 -0
  108. data/lib/outhad/integrations/destination/postgresql/config/spec.json +68 -0
  109. data/lib/outhad/integrations/destination/postgresql/icon.svg +20 -0
  110. data/lib/outhad/integrations/destination/qdrant/client.rb +184 -0
  111. data/lib/outhad/integrations/destination/qdrant/config/meta.json +15 -0
  112. data/lib/outhad/integrations/destination/qdrant/config/spec.json +23 -0
  113. data/lib/outhad/integrations/destination/qdrant/icon.svg +1 -0
  114. data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/client.rb +136 -0
  115. data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/config/catalog.json +6 -0
  116. data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/config/meta.json +16 -0
  117. data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/config/spec.json +52 -0
  118. data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/icon.svg +16 -0
  119. data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/schema_helper.rb +132 -0
  120. data/lib/outhad/integrations/destination/salesforce_crm/client.rb +114 -0
  121. data/lib/outhad/integrations/destination/salesforce_crm/config/catalog.json +320 -0
  122. data/lib/outhad/integrations/destination/salesforce_crm/config/meta.json +15 -0
  123. data/lib/outhad/integrations/destination/salesforce_crm/config/spec.json +46 -0
  124. data/lib/outhad/integrations/destination/salesforce_crm/icon.svg +16 -0
  125. data/lib/outhad/integrations/destination/sftp/client.rb +186 -0
  126. data/lib/outhad/integrations/destination/sftp/config/catalog.json +16 -0
  127. data/lib/outhad/integrations/destination/sftp/config/meta.json +16 -0
  128. data/lib/outhad/integrations/destination/sftp/config/spec.json +73 -0
  129. data/lib/outhad/integrations/destination/sftp/icon.svg +1 -0
  130. data/lib/outhad/integrations/destination/slack/client.rb +125 -0
  131. data/lib/outhad/integrations/destination/slack/config/catalog.json +22 -0
  132. data/lib/outhad/integrations/destination/slack/config/meta.json +15 -0
  133. data/lib/outhad/integrations/destination/slack/config/spec.json +23 -0
  134. data/lib/outhad/integrations/destination/slack/icon.svg +26 -0
  135. data/lib/outhad/integrations/destination/stripe/client.rb +94 -0
  136. data/lib/outhad/integrations/destination/stripe/config/catalog.json +128 -0
  137. data/lib/outhad/integrations/destination/stripe/config/meta.json +15 -0
  138. data/lib/outhad/integrations/destination/stripe/config/spec.json +18 -0
  139. data/lib/outhad/integrations/destination/stripe/icon.svg +10 -0
  140. data/lib/outhad/integrations/destination/zendesk/client.rb +132 -0
  141. data/lib/outhad/integrations/destination/zendesk/config/catalog.json +110 -0
  142. data/lib/outhad/integrations/destination/zendesk/config/meta.json +18 -0
  143. data/lib/outhad/integrations/destination/zendesk/config/spec.json +32 -0
  144. data/lib/outhad/integrations/destination/zendesk/icon.svg +63 -0
  145. data/lib/outhad/integrations/protocol/protocol.json +189 -0
  146. data/lib/outhad/integrations/protocol/protocol.rb +228 -0
  147. data/lib/outhad/integrations/rollout.rb +66 -0
  148. data/lib/outhad/integrations/service.rb +55 -0
  149. data/lib/outhad/integrations/source/amazon_s3/client.rb +235 -0
  150. data/lib/outhad/integrations/source/amazon_s3/config/meta.json +16 -0
  151. data/lib/outhad/integrations/source/amazon_s3/config/spec.json +119 -0
  152. data/lib/outhad/integrations/source/amazon_s3/icon.svg +34 -0
  153. data/lib/outhad/integrations/source/anthropic/client.rb +135 -0
  154. data/lib/outhad/integrations/source/anthropic/config/catalog.json +6 -0
  155. data/lib/outhad/integrations/source/anthropic/config/meta.json +16 -0
  156. data/lib/outhad/integrations/source/anthropic/config/spec.json +56 -0
  157. data/lib/outhad/integrations/source/anthropic/icon.svg +1 -0
  158. data/lib/outhad/integrations/source/aws_athena/client.rb +109 -0
  159. data/lib/outhad/integrations/source/aws_athena/config/meta.json +16 -0
  160. data/lib/outhad/integrations/source/aws_athena/config/spec.json +63 -0
  161. data/lib/outhad/integrations/source/aws_athena/icon.svg +22 -0
  162. data/lib/outhad/integrations/source/aws_bedrock_model/client.rb +91 -0
  163. data/lib/outhad/integrations/source/aws_bedrock_model/config/catalog.json +6 -0
  164. data/lib/outhad/integrations/source/aws_bedrock_model/config/meta.json +16 -0
  165. data/lib/outhad/integrations/source/aws_bedrock_model/config/spec.json +58 -0
  166. data/lib/outhad/integrations/source/aws_bedrock_model/icon.svg +1 -0
  167. data/lib/outhad/integrations/source/aws_sagemaker_model/client.rb +79 -0
  168. data/lib/outhad/integrations/source/aws_sagemaker_model/config/catalog.json +6 -0
  169. data/lib/outhad/integrations/source/aws_sagemaker_model/config/meta.json +16 -0
  170. data/lib/outhad/integrations/source/aws_sagemaker_model/config/spec.json +52 -0
  171. data/lib/outhad/integrations/source/aws_sagemaker_model/icon.svg +7 -0
  172. data/lib/outhad/integrations/source/bigquery/client.rb +98 -0
  173. data/lib/outhad/integrations/source/bigquery/config/meta.json +16 -0
  174. data/lib/outhad/integrations/source/bigquery/config/spec.json +83 -0
  175. data/lib/outhad/integrations/source/bigquery/icon.svg +1 -0
  176. data/lib/outhad/integrations/source/clickhouse/client.rb +102 -0
  177. data/lib/outhad/integrations/source/clickhouse/config/meta.json +16 -0
  178. data/lib/outhad/integrations/source/clickhouse/config/spec.json +42 -0
  179. data/lib/outhad/integrations/source/clickhouse/icon.svg +25 -0
  180. data/lib/outhad/integrations/source/databricks/client.rb +98 -0
  181. data/lib/outhad/integrations/source/databricks/config/meta.json +17 -0
  182. data/lib/outhad/integrations/source/databricks/config/spec.json +56 -0
  183. data/lib/outhad/integrations/source/databricks/icon.svg +19 -0
  184. data/lib/outhad/integrations/source/databrics_model/client.rb +89 -0
  185. data/lib/outhad/integrations/source/databrics_model/config/catalog.json +6 -0
  186. data/lib/outhad/integrations/source/databrics_model/config/meta.json +17 -0
  187. data/lib/outhad/integrations/source/databrics_model/config/spec.json +63 -0
  188. data/lib/outhad/integrations/source/databrics_model/icon.svg +19 -0
  189. data/lib/outhad/integrations/source/firecrawl/client.rb +151 -0
  190. data/lib/outhad/integrations/source/firecrawl/config/catalog.json +29 -0
  191. data/lib/outhad/integrations/source/firecrawl/config/meta.json +17 -0
  192. data/lib/outhad/integrations/source/firecrawl/config/spec.json +31 -0
  193. data/lib/outhad/integrations/source/firecrawl/icon.svg +4 -0
  194. data/lib/outhad/integrations/source/generic_open_ai/client.rb +118 -0
  195. data/lib/outhad/integrations/source/generic_open_ai/config/catalog.json +6 -0
  196. data/lib/outhad/integrations/source/generic_open_ai/config/meta.json +16 -0
  197. data/lib/outhad/integrations/source/generic_open_ai/config/spec.json +63 -0
  198. data/lib/outhad/integrations/source/generic_open_ai/icon.svg +6 -0
  199. data/lib/outhad/integrations/source/google_vertex_model/client.rb +83 -0
  200. data/lib/outhad/integrations/source/google_vertex_model/config/catalog.json +6 -0
  201. data/lib/outhad/integrations/source/google_vertex_model/config/meta.json +17 -0
  202. data/lib/outhad/integrations/source/google_vertex_model/config/spec.json +105 -0
  203. data/lib/outhad/integrations/source/google_vertex_model/icon.svg +2 -0
  204. data/lib/outhad/integrations/source/http_model/client.rb +108 -0
  205. data/lib/outhad/integrations/source/http_model/config/catalog.json +6 -0
  206. data/lib/outhad/integrations/source/http_model/config/meta.json +16 -0
  207. data/lib/outhad/integrations/source/http_model/config/spec.json +70 -0
  208. data/lib/outhad/integrations/source/http_model/icon.svg +9 -0
  209. data/lib/outhad/integrations/source/intuit_quick_books/client.rb +213 -0
  210. data/lib/outhad/integrations/source/intuit_quick_books/config/catalog.json +6 -0
  211. data/lib/outhad/integrations/source/intuit_quick_books/config/meta.json +17 -0
  212. data/lib/outhad/integrations/source/intuit_quick_books/config/spec.json +44 -0
  213. data/lib/outhad/integrations/source/intuit_quick_books/icon.svg +1 -0
  214. data/lib/outhad/integrations/source/maria_db/client.rb +92 -0
  215. data/lib/outhad/integrations/source/maria_db/config/meta.json +16 -0
  216. data/lib/outhad/integrations/source/maria_db/config/spec.json +48 -0
  217. data/lib/outhad/integrations/source/maria_db/icon.svg +15 -0
  218. data/lib/outhad/integrations/source/odoo/client.rb +106 -0
  219. data/lib/outhad/integrations/source/odoo/config/meta.json +15 -0
  220. data/lib/outhad/integrations/source/odoo/config/spec.json +39 -0
  221. data/lib/outhad/integrations/source/odoo/icon.svg +21 -0
  222. data/lib/outhad/integrations/source/open_ai/client.rb +118 -0
  223. data/lib/outhad/integrations/source/open_ai/config/catalog.json +6 -0
  224. data/lib/outhad/integrations/source/open_ai/config/meta.json +16 -0
  225. data/lib/outhad/integrations/source/open_ai/config/spec.json +56 -0
  226. data/lib/outhad/integrations/source/open_ai/icon.svg +1 -0
  227. data/lib/outhad/integrations/source/oracle_db/client.rb +127 -0
  228. data/lib/outhad/integrations/source/oracle_db/config/meta.json +16 -0
  229. data/lib/outhad/integrations/source/oracle_db/config/spec.json +47 -0
  230. data/lib/outhad/integrations/source/oracle_db/icon.svg +4 -0
  231. data/lib/outhad/integrations/source/pinecone_db/client.rb +73 -0
  232. data/lib/outhad/integrations/source/pinecone_db/config/catalog.json +6 -0
  233. data/lib/outhad/integrations/source/pinecone_db/config/meta.json +16 -0
  234. data/lib/outhad/integrations/source/pinecone_db/config/spec.json +34 -0
  235. data/lib/outhad/integrations/source/pinecone_db/icon.svg +2 -0
  236. data/lib/outhad/integrations/source/postgresql/client.rb +112 -0
  237. data/lib/outhad/integrations/source/postgresql/config/meta.json +16 -0
  238. data/lib/outhad/integrations/source/postgresql/config/spec.json +86 -0
  239. data/lib/outhad/integrations/source/postgresql/icon.svg +20 -0
  240. data/lib/outhad/integrations/source/qdrant/client.rb +86 -0
  241. data/lib/outhad/integrations/source/qdrant/config/catalog.json +6 -0
  242. data/lib/outhad/integrations/source/qdrant/config/meta.json +16 -0
  243. data/lib/outhad/integrations/source/qdrant/config/spec.json +29 -0
  244. data/lib/outhad/integrations/source/qdrant/icon.svg +1 -0
  245. data/lib/outhad/integrations/source/redshift/client.rb +109 -0
  246. data/lib/outhad/integrations/source/redshift/config/meta.json +16 -0
  247. data/lib/outhad/integrations/source/redshift/config/spec.json +71 -0
  248. data/lib/outhad/integrations/source/redshift/icon.svg +15 -0
  249. data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/client.rb +133 -0
  250. data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/config/catalog.json +6 -0
  251. data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/config/meta.json +18 -0
  252. data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/config/spec.json +53 -0
  253. data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/icon.svg +16 -0
  254. data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/schema_helper.rb +130 -0
  255. data/lib/outhad/integrations/source/sftp/client.rb +133 -0
  256. data/lib/outhad/integrations/source/sftp/config/meta.json +16 -0
  257. data/lib/outhad/integrations/source/sftp/config/spec.json +59 -0
  258. data/lib/outhad/integrations/source/sftp/icon.svg +1 -0
  259. data/lib/outhad/integrations/source/snowflake/client.rb +92 -0
  260. data/lib/outhad/integrations/source/snowflake/config/meta.json +16 -0
  261. data/lib/outhad/integrations/source/snowflake/config/spec.json +82 -0
  262. data/lib/outhad/integrations/source/snowflake/icon.svg +10 -0
  263. data/lib/outhad/integrations/source/watsonx_ai/client.rb +194 -0
  264. data/lib/outhad/integrations/source/watsonx_ai/config/catalog.json +6 -0
  265. data/lib/outhad/integrations/source/watsonx_ai/config/meta.json +16 -0
  266. data/lib/outhad/integrations/source/watsonx_ai/config/spec.json +74 -0
  267. data/lib/outhad/integrations/source/watsonx_ai/icon.svg +1 -0
  268. data/lib/outhad/integrations/source/watsonx_data/client.rb +146 -0
  269. data/lib/outhad/integrations/source/watsonx_data/config/meta.json +17 -0
  270. data/lib/outhad/integrations/source/watsonx_data/config/spec.json +72 -0
  271. data/lib/outhad/integrations/source/watsonx_data/icon.svg +1 -0
  272. data/lib/outhad/integrations.rb +129 -0
  273. data/outhad-integrations.gemspec +79 -0
  274. data/sig/outhad/integrations.rbs +6 -0
  275. metadata +866 -0
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Outhad::Integrations::Destination
4
+ module PineconeDB
5
+ include Outhad::Integrations::Core
6
+ PINECONE_OBJECTS = [
7
+ { column_name: "id", data_type: "string", is_nullable: false },
8
+ { column_name: "value", data_type: "vector", is_nullable: false },
9
+ { column_name: "meta_data", data_type: "string", is_nullable: false }
10
+ ].freeze
11
+ class Client < DestinationConnector
12
+ def check_connection(connection_config)
13
+ connection_config = connection_config.with_indifferent_access
14
+ create_connection(connection_config)
15
+ result = @pinecone.describe_index(@index_name)
16
+ if result
17
+ success_status
18
+ else
19
+ failure_status(nil)
20
+ end
21
+ rescue StandardError => e
22
+ handle_exception(e, { context: "PINECONE:CHECK_CONNECTION:EXCEPTION", type: "error" })
23
+ failure_status(e)
24
+ end
25
+
26
+ def discover(connection_config)
27
+ connection_config = connection_config.with_indifferent_access
28
+ create_connection(connection_config)
29
+ pinecone_index = @pinecone.index(@index_name)
30
+ response = pinecone_index.describe_index_stats
31
+ results = JSON.parse(response.body)
32
+ records = results["namespaces"].keys
33
+ catalog = Catalog.new(streams: create_streams(records))
34
+ catalog.to_outhad_message
35
+ rescue StandardError => e
36
+ handle_exception(e, {
37
+ context: "PINECONE:DISCOVER:EXCEPTION",
38
+ type: "error"
39
+ })
40
+ end
41
+
42
+ def write(sync_config, records, _action = "upsert")
43
+ @sync_config = sync_config
44
+ connection_config = sync_config.destination.connection_specification.with_indifferent_access
45
+ create_connection(connection_config)
46
+ process_records(records, sync_config.stream)
47
+ rescue StandardError => e
48
+ handle_exception(e, {
49
+ context: "PINECONE:WRITE:EXCEPTION",
50
+ type: "error",
51
+ sync_id: @sync_config.sync_id,
52
+ sync_run_id: @sync_config.sync_run_id
53
+ })
54
+ end
55
+
56
+ private
57
+
58
+ def create_connection(connection_config)
59
+ initialize_client(connection_config)
60
+ Pinecone.configure do |config|
61
+ config.api_key = @api_key
62
+ config.environment = @region
63
+ end
64
+ @pinecone = Pinecone::Client.new
65
+ end
66
+
67
+ def initialize_client(connection_config)
68
+ @api_key = connection_config["api_key"]
69
+ @region = connection_config["region"]
70
+ @index_name = connection_config["index_name"]
71
+ end
72
+
73
+ def process_records(records, stream)
74
+ log_message_array = []
75
+ write_success = 0
76
+ write_failure = 0
77
+ properties = stream.json_schema[:properties]
78
+
79
+ records.each do |record_object|
80
+ record = extract_data(record_object, properties)
81
+ @namespace = stream.name
82
+ args = [@index_name, @namespace, record]
83
+ begin
84
+ pinecone_index = @pinecone.index(@index_name)
85
+ response = send_to_pinecone(pinecone_index, record)
86
+ if success?(response)
87
+ write_success += 1
88
+ else
89
+ write_failure += 1
90
+ end
91
+ log_message_array << log_request_response("info", args, response)
92
+ rescue StandardError => e
93
+ handle_exception(e, {
94
+ context: "PINECONE:WRITE:EXCEPTION",
95
+ type: "error",
96
+ sync_id: @sync_config.sync_id,
97
+ sync_run_id: @sync_config.sync_run_id
98
+ })
99
+ write_failure += 1
100
+ log_message_array << log_request_response("error", args, e.message)
101
+ end
102
+ end
103
+ tracking_message(write_success, write_failure, log_message_array)
104
+ end
105
+
106
+ def parse_meta_data(vector_meta_data)
107
+ return {} if vector_meta_data.nil?
108
+
109
+ metadata = vector_meta_data.to_s
110
+ metadata = metadata.gsub(/([{,]\s*)([A-Za-z_]\w*)(\s*:)/, '\1"\2"\3')
111
+ metadata = metadata.gsub(/:\s*([A-Za-z_]\w*)/, ': "\1"')
112
+
113
+ JSON.parse(metadata)
114
+ rescue JSON::ParserError
115
+ {}
116
+ end
117
+
118
+ def send_to_pinecone(pinecone_index, record)
119
+ meta_data = parse_meta_data(record[:meta_data])
120
+ pinecone_index.upsert(
121
+ namespace: @namespace,
122
+ vectors: [
123
+ {
124
+ id: record[:id].to_s,
125
+ values: record[:value],
126
+ metadata: meta_data
127
+ }
128
+ ]
129
+ )
130
+ end
131
+
132
+ def create_streams(records)
133
+ group_by_table(records).map do |r|
134
+ Outhad::Integrations::Protocol::Stream.new(name: r[:tablename], action: StreamAction["create"], json_schema: convert_to_json_schema(r[:columns]))
135
+ end
136
+ end
137
+
138
+ def group_by_table(records)
139
+ records.map do |table_name|
140
+ {
141
+ tablename: table_name,
142
+ columns: PINECONE_OBJECTS.map do |column|
143
+ {
144
+ column_name: column[:column_name],
145
+ type: column[:data_type],
146
+ optional: column[:is_nullable]
147
+ }
148
+ end
149
+ }
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,15 @@
1
+ {
2
+ "data": {
3
+ "name": "PineconeDB",
4
+ "title": "Pinecone DB",
5
+ "connector_type": "destination",
6
+ "category": "Database",
7
+ "documentation_url": "https://docs.squared.ai/guides/destinations/retl-destinations/database/pinecone_db",
8
+ "github_issue_label": "destination-pinecone-db",
9
+ "icon": "icon.svg",
10
+ "license": "MIT",
11
+ "release_stage": "alpha",
12
+ "support_level": "community",
13
+ "tags": ["language:ruby", "outhad"]
14
+ }
15
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "documentation_url": "https://docs.squared.ai/guides/destinations/retl-destinations/database/oracle",
3
+ "stream_type": "dynamic",
4
+ "connector_query_type": "raw_sql",
5
+ "connection_specification": {
6
+ "$schema": "http://json-schema.org/draft-07/schema#",
7
+ "title": "Pinecone DB",
8
+ "type": "object",
9
+ "required": ["api_key", "region", "index_name"],
10
+ "properties": {
11
+ "api_key": {
12
+ "type": "string",
13
+ "outhad_secret": true,
14
+ "title": "API Key",
15
+ "description": "Your secret Pinecone API key used to authenticate requests.",
16
+ "order": 0
17
+ },
18
+ "region": {
19
+ "type": "string",
20
+ "title": "Region",
21
+ "description": "The Pinecone region where your index is hosted (e.g., 'us-east-1').",
22
+ "order": 1
23
+ },
24
+ "index_name": {
25
+ "type": "string",
26
+ "title": "Index Name",
27
+ "description": "The name of the Pinecone index where vectors will be written.",
28
+ "order": 2
29
+ }
30
+ }
31
+ }
32
+ }
@@ -0,0 +1 @@
1
+ <svg width="256" height="287.319" viewBox="0 0 256 287.319" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid"><title>Pinecone</title><g><path d="M108.633615,254.43629 C117.713862,254.43629 125.074857,261.797284 125.074857,270.877532 C125.074857,279.957779 117.713862,287.318774 108.633615,287.318774 C99.5533677,287.318774 92.1923728,279.957779 92.1923728,270.877532 C92.1923728,261.797284 99.5533677,254.43629 108.633615,254.43629 Z M199.849665,224.438339 L216.09705,229.252379 L203.199913,272.780219 C202.072982,276.58361 198.458049,279.095992 194.500389,278.826397 L190.516677,278.552973 L190.419263,278.633409 L149.02918,275.728903 L150.180842,258.822508 L177.989056,260.709686 L159.783784,234.447622 L173.709616,224.792379 L191.938895,251.08702 L199.849665,224.438339 Z M23.0126771,194.347476 L39.9158866,195.544979 L37.935897,223.348728 L64.1501315,205.120082 L73.8271476,219.030793 L47.578736,237.278394 L74.3707554,245.173037 L69.5818063,261.427835 L25.8485266,248.543243 C22.0304448,247.418369 19.5101155,243.787479 19.7913963,239.817092 L23.0126771,194.347476 Z M132.151306,170.671396 L162.658679,207.503468 L148.909247,218.891886 L130.753266,196.972134 L124.866941,230.673893 L107.280249,227.599613 L113.172232,193.845272 L88.7296311,208.256891 L79.6674587,192.874434 L120.745504,168.674377 C124.522104,166.449492 129.355297,167.295726 132.151306,170.671396 Z M217.504528,145.960198 L232.744017,137.668804 L254.94482,178.473633 C256.889641,182.048192 256.088221,186.494171 253.017682,189.164674 L249.876622,191.878375 L217.826246,219.77131 L206.441034,206.680621 L227.988588,187.934494 L195.893546,182.152609 L198.972402,165.078949 L231.044844,170.857793 L217.504528,145.960198 Z M37.7821805,103.299272 L49.2622123,116.306888 L28.0106317,135.050179 L60.1668233,140.664193 L57.1863573,157.755303 L24.9947229,152.136967 L38.822104,177.134576 L23.6411026,185.532577 L1.08439616,144.756992 C-0.885025494,141.196884 -0.115545265,136.746375 2.93488097,134.054184 L37.7821805,103.299272 Z M146.476311,89.8796828 L176.88045,126.612847 L163.1271,137.996532 L144.975445,116.067101 L139.08912,149.778947 L121.502428,146.704666 L127.374238,113.081452 L103.025237,127.354817 L93.9976317,111.952048 L131.398812,90.0233663 L131.435631,89.880899 L131.600545,89.9023265 L135.085833,87.870141 C138.861877,85.6569913 143.68556,86.5079996 146.476311,89.8796828 Z M185.655786,71.8143168 L192.305535,55.7902703 L235.318239,73.6399229 C239.072486,75.1978811 241.2415,79.1537636 240.536356,83.1568091 L239.820231,87.1385839 L232.47517,128.919545 L215.389188,125.909819 L220.312646,97.9413879 L191.776157,113.7129 L183.390302,98.5251862 L211.981072,82.7408038 L185.655786,71.8143168 Z M103.71696,40.2373824 L104.456513,57.5706533 L76.0432671,58.785006 L97.4730368,83.2749086 L84.4165529,94.6993319 L62.9507932,70.1728358 L57.949673,98.1737132 L40.8716575,95.1191088 L49.0561498,49.3603563 C49.771444,45.3612115 53.1664633,42.3942036 57.2253811,42.2210231 L61.246149,42.0411642 L61.3363168,41.9758 L103.71696,40.2373824 Z M161.838155,3.27194826 L192.104824,40.2369789 L178.291207,51.5474574 L160.327329,29.6043227 L154.268381,63.2715157 L136.697231,60.1096121 L142.766468,26.3665075 L118.24002,40.7062765 L109.232678,25.2916494 L150.427675,1.21987397 C154.218286,-0.995121237 159.056796,-0.124957814 161.838155,3.27194826 Z" fill="#201D1E"/></g></svg>
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pg"
4
+
5
+ module Outhad::Integrations::Destination
6
+ module Postgresql
7
+ include Outhad::Integrations::Core
8
+ class Client < DestinationConnector
9
+ def check_connection(connection_config)
10
+ connection_config = connection_config.with_indifferent_access
11
+ create_connection(connection_config)
12
+ ConnectionStatus.new(
13
+ status: ConnectionStatusType["succeeded"]
14
+ ).to_outhad_message
15
+ rescue PG::Error => e
16
+ ConnectionStatus.new(
17
+ status: ConnectionStatusType["failed"], message: e.message
18
+ ).to_outhad_message
19
+ end
20
+
21
+ def discover(connection_config)
22
+ connection_config = connection_config.with_indifferent_access
23
+ query = "SELECT table_name, column_name,
24
+ CASE WHEN data_type = 'USER-DEFINED' THEN udt_name ELSE data_type END
25
+ AS data_type,
26
+ is_nullable
27
+ FROM information_schema.columns
28
+ WHERE table_schema = '#{connection_config[:schema]}' AND table_catalog = '#{connection_config[:database]}'
29
+ ORDER BY table_name, ordinal_position;"
30
+
31
+ db = create_connection(connection_config)
32
+ records = db.exec(query) do |result|
33
+ result.map do |row|
34
+ row
35
+ end
36
+ end
37
+ catalog = Catalog.new(streams: create_streams(records))
38
+ catalog.to_outhad_message
39
+ rescue StandardError => e
40
+ handle_exception(e, {
41
+ context: "POSTGRESQL:DISCOVER:EXCEPTION",
42
+ type: "error"
43
+ })
44
+ ensure
45
+ db&.close
46
+ end
47
+
48
+ def write(sync_config, records, action = "destination_insert")
49
+ connection_config = sync_config.destination.connection_specification.with_indifferent_access
50
+ table_name = sync_config.stream.name
51
+ primary_key = sync_config.model.primary_key
52
+ log_message_array = []
53
+ db = create_connection(connection_config)
54
+
55
+ write_success = 0
56
+ write_failure = 0
57
+
58
+ records.each do |record|
59
+ query = Outhad::Integrations::Core::QueryBuilder.perform(action, table_name, record, primary_key)
60
+ logger.debug("POSTGRESQL:WRITE:QUERY query = #{query} sync_id = #{sync_config.sync_id} sync_run_id = #{sync_config.sync_run_id}")
61
+ begin
62
+ response = db.exec(query)
63
+ write_success += 1
64
+ log_message_array << log_request_response("info", query, response)
65
+ rescue StandardError => e
66
+ handle_exception(e, {
67
+ context: "POSTGRESQL:RECORD:WRITE:EXCEPTION",
68
+ type: "error",
69
+ sync_id: sync_config.sync_id,
70
+ sync_run_id: sync_config.sync_run_id
71
+ })
72
+ write_failure += 1
73
+ log_message_array << log_request_response("error", query, e.message)
74
+ end
75
+ end
76
+ tracking_message(write_success, write_failure, log_message_array)
77
+ rescue StandardError => e
78
+ handle_exception(e, {
79
+ context: "POSTGRESQL:RECORD:WRITE:EXCEPTION",
80
+ type: "error",
81
+ sync_id: sync_config.sync_id,
82
+ sync_run_id: sync_config.sync_run_id
83
+ })
84
+ end
85
+
86
+ private
87
+
88
+ def query(connection, query)
89
+ connection.exec(query) do |result|
90
+ result.map do |row|
91
+ RecordMessage.new(data: row, emitted_at: Time.now.to_i).to_outhad_message
92
+ end
93
+ end
94
+ end
95
+
96
+ def create_connection(connection_config)
97
+ raise "Unsupported Auth type" unless connection_config[:credentials][:auth_type] == "username/password"
98
+
99
+ PG.connect(
100
+ host: connection_config[:host],
101
+ dbname: connection_config[:database],
102
+ user: connection_config[:credentials][:username],
103
+ password: connection_config[:credentials][:password],
104
+ port: connection_config[:port]
105
+ )
106
+ end
107
+
108
+ def create_streams(records)
109
+ group_by_table(records).map do |r|
110
+ Outhad::Integrations::Protocol::Stream.new(name: r[:tablename], action: StreamAction["fetch"], json_schema: convert_to_json_schema(r[:columns]))
111
+ end
112
+ end
113
+
114
+ def group_by_table(records)
115
+ records.group_by { |entry| entry["table_name"] }.map do |table_name, columns|
116
+ {
117
+ tablename: table_name,
118
+ columns: columns.map do |column|
119
+ {
120
+ column_name: column["column_name"],
121
+ type: column["data_type"],
122
+ optional: column["is_nullable"] == "YES"
123
+ }
124
+ end
125
+ }
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,15 @@
1
+ {
2
+ "data": {
3
+ "name": "Postgresql",
4
+ "title": "PostgreSQL",
5
+ "connector_type": "destination",
6
+ "category": "Database",
7
+ "documentation_url": "https://docs.squared.ai/guides/destinations/retl-destinations/database/postgresql",
8
+ "github_issue_label": "destination-postgresql",
9
+ "icon": "icon.svg",
10
+ "license": "MIT",
11
+ "release_stage": "alpha",
12
+ "support_level": "community",
13
+ "tags": ["language:ruby", "outhad"]
14
+ }
15
+ }
@@ -0,0 +1,68 @@
1
+ {
2
+ "documentation_url": "https://docs.squared.ai/guides/destinations/retl-destinations/database/postgresql",
3
+ "stream_type": "dynamic",
4
+ "connection_specification": {
5
+ "$schema": "http://json-schema.org/draft-07/schema#",
6
+ "title": "Postgresql",
7
+ "type": "object",
8
+ "required": ["host", "port", "database", "schema"],
9
+ "properties": {
10
+ "credentials": {
11
+ "title": "",
12
+ "type": "object",
13
+ "required": ["auth_type", "username", "password"],
14
+ "properties": {
15
+ "auth_type": {
16
+ "type": "string",
17
+ "default": "username/password",
18
+ "order": 0,
19
+ "readOnly": true
20
+ },
21
+ "username": {
22
+ "description": "Username refers to your individual PostgreSQL login credentials. At a minimum, the user associated with these credentials must be granted read access to the data intended for synchronization.",
23
+ "examples": ["POSTGRESQL_USER"],
24
+ "type": "string",
25
+ "title": "Username",
26
+ "order": 1
27
+ },
28
+ "password": {
29
+ "description": "This field requires the password associated with the user account specified in the preceding section.",
30
+ "type": "string",
31
+ "outhad_secret": true,
32
+ "title": "Password",
33
+ "order": 2
34
+ }
35
+ },
36
+ "order": 0
37
+ },
38
+ "host": {
39
+ "description": "The hostname or IP address of your PostgreSQL server.",
40
+ "examples": ["127.0.0.1"],
41
+ "type": "string",
42
+ "title": "Host",
43
+ "order": 1
44
+ },
45
+ "port": {
46
+ "description": "The port number for your PostgreSQL server, which defaults to 5432, may vary based on your configuration. ",
47
+ "examples": ["5432"],
48
+ "type": "string",
49
+ "title": "Port",
50
+ "order": 2
51
+ },
52
+ "database": {
53
+ "description": "The specific PostgreSQL database to connect to.",
54
+ "examples": ["POSTGRESQL_DB"],
55
+ "type": "string",
56
+ "title": "Database",
57
+ "order": 3
58
+ },
59
+ "schema": {
60
+ "description": "The schema within the PostgreSQL database.",
61
+ "examples": ["POSTGRESQL_SCHEMA"],
62
+ "type": "string",
63
+ "title": "Schema",
64
+ "order": 4
65
+ }
66
+ }
67
+ }
68
+ }
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
3
+ <svg width="432.071pt" height="445.383pt" viewBox="0 0 432.071 445.383" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
4
+ <g id="orginal" style="fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
5
+ </g>
6
+ <g id="Layer_x0020_3" style="fill-rule:nonzero;clip-rule:nonzero;fill:none;stroke:#FFFFFF;stroke-width:12.4651;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;">
7
+ <path style="fill:#000000;stroke:#000000;stroke-width:37.3953;stroke-linecap:butt;stroke-linejoin:miter;" d="M323.205,324.227c2.833-23.601,1.984-27.062,19.563-23.239l4.463,0.392c13.517,0.615,31.199-2.174,41.587-7c22.362-10.376,35.622-27.7,13.572-23.148c-50.297,10.376-53.755-6.655-53.755-6.655c53.111-78.803,75.313-178.836,56.149-203.322 C352.514-5.534,262.036,26.049,260.522,26.869l-0.482,0.089c-9.938-2.062-21.06-3.294-33.554-3.496c-22.761-0.374-40.032,5.967-53.133,15.904c0,0-161.408-66.498-153.899,83.628c1.597,31.936,45.777,241.655,98.47,178.31 c19.259-23.163,37.871-42.748,37.871-42.748c9.242,6.14,20.307,9.272,31.912,8.147l0.897-0.765c-0.281,2.876-0.157,5.689,0.359,9.019c-13.572,15.167-9.584,17.83-36.723,23.416c-27.457,5.659-11.326,15.734-0.797,18.367c12.768,3.193,42.305,7.716,62.268-20.224 l-0.795,3.188c5.325,4.26,4.965,30.619,5.72,49.452c0.756,18.834,2.017,36.409,5.856,46.771c3.839,10.36,8.369,37.05,44.036,29.406c29.809-6.388,52.6-15.582,54.677-101.107"/>
8
+ <path style="fill:#336791;stroke:none;" d="M402.395,271.23c-50.302,10.376-53.76-6.655-53.76-6.655c53.111-78.808,75.313-178.843,56.153-203.326c-52.27-66.785-142.752-35.2-144.262-34.38l-0.486,0.087c-9.938-2.063-21.06-3.292-33.56-3.496c-22.761-0.373-40.026,5.967-53.127,15.902 c0,0-161.411-66.495-153.904,83.63c1.597,31.938,45.776,241.657,98.471,178.312c19.26-23.163,37.869-42.748,37.869-42.748c9.243,6.14,20.308,9.272,31.908,8.147l0.901-0.765c-0.28,2.876-0.152,5.689,0.361,9.019c-13.575,15.167-9.586,17.83-36.723,23.416 c-27.459,5.659-11.328,15.734-0.796,18.367c12.768,3.193,42.307,7.716,62.266-20.224l-0.796,3.188c5.319,4.26,9.054,27.711,8.428,48.969c-0.626,21.259-1.044,35.854,3.147,47.254c4.191,11.4,8.368,37.05,44.042,29.406c29.809-6.388,45.256-22.942,47.405-50.555 c1.525-19.631,4.976-16.729,5.194-34.28l2.768-8.309c3.192-26.611,0.507-35.196,18.872-31.203l4.463,0.392c13.517,0.615,31.208-2.174,41.591-7c22.358-10.376,35.618-27.7,13.573-23.148z"/>
9
+ <path d="M215.866,286.484c-1.385,49.516,0.348,99.377,5.193,111.495c4.848,12.118,15.223,35.688,50.9,28.045c29.806-6.39,40.651-18.756,45.357-46.051c3.466-20.082,10.148-75.854,11.005-87.281"/>
10
+ <path d="M173.104,38.256c0,0-161.521-66.016-154.012,84.109c1.597,31.938,45.779,241.664,98.473,178.316c19.256-23.166,36.671-41.335,36.671-41.335"/>
11
+ <path d="M260.349,26.207c-5.591,1.753,89.848-34.889,144.087,34.417c19.159,24.484-3.043,124.519-56.153,203.329"/>
12
+ <path style="stroke-linejoin:bevel;" d="M348.282,263.953c0,0,3.461,17.036,53.764,6.653c22.04-4.552,8.776,12.774-13.577,23.155c-18.345,8.514-59.474,10.696-60.146-1.069c-1.729-30.355,21.647-21.133,19.96-28.739c-1.525-6.85-11.979-13.573-18.894-30.338 c-6.037-14.633-82.796-126.849,21.287-110.183c3.813-0.789-27.146-99.002-124.553-100.599c-97.385-1.597-94.19,119.762-94.19,119.762"/>
13
+ <path d="M188.604,274.334c-13.577,15.166-9.584,17.829-36.723,23.417c-27.459,5.66-11.326,15.733-0.797,18.365c12.768,3.195,42.307,7.718,62.266-20.229c6.078-8.509-0.036-22.086-8.385-25.547c-4.034-1.671-9.428-3.765-16.361,3.994z"/>
14
+ <path d="M187.715,274.069c-1.368-8.917,2.93-19.528,7.536-31.942c6.922-18.626,22.893-37.255,10.117-96.339c-9.523-44.029-73.396-9.163-73.436-3.193c-0.039,5.968,2.889,30.26-1.067,58.548c-5.162,36.913,23.488,68.132,56.479,64.938"/>
15
+ <path style="fill:#FFFFFF;stroke-width:4.155;stroke-linecap:butt;stroke-linejoin:miter;" d="M172.517,141.7c-0.288,2.039,3.733,7.48,8.976,8.207c5.234,0.73,9.714-3.522,9.998-5.559c0.284-2.039-3.732-4.285-8.977-5.015c-5.237-0.731-9.719,0.333-9.996,2.367z"/>
16
+ <path style="fill:#FFFFFF;stroke-width:2.0775;stroke-linecap:butt;stroke-linejoin:miter;" d="M331.941,137.543c0.284,2.039-3.732,7.48-8.976,8.207c-5.238,0.73-9.718-3.522-10.005-5.559c-0.277-2.039,3.74-4.285,8.979-5.015c5.239-0.73,9.718,0.333,10.002,2.368z"/>
17
+ <path d="M350.676,123.432c0.863,15.994-3.445,26.888-3.988,43.914c-0.804,24.748,11.799,53.074-7.191,81.435"/>
18
+ <path style="stroke-width:3;" d="M0,60.232"/>
19
+ </g>
20
+ </svg>
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Outhad::Integrations::Destination
4
+ module Qdrant
5
+ include Outhad::Integrations::Core
6
+ class Client < DestinationConnector
7
+ def check_connection(connection_config)
8
+ connection_config = connection_config.with_indifferent_access
9
+ api_url = connection_config[:api_url]
10
+ api_key = connection_config[:api_key]
11
+
12
+ response = Outhad::Integrations::Core::HttpClient.request(
13
+ api_url,
14
+ HTTP_GET,
15
+ headers: auth_headers(api_key)
16
+ )
17
+ if success?(response)
18
+ success_status
19
+ else
20
+ failure_status(nil)
21
+ end
22
+ rescue StandardError => e
23
+ handle_exception(e, {
24
+ context: "QDRANT:CHECK_CONNECTION:EXCEPTION",
25
+ type: "error"
26
+ })
27
+ failure_status(e)
28
+ end
29
+
30
+ def discover(connection_config = nil)
31
+ connection_config = connection_config.with_indifferent_access
32
+ @api_url = connection_config[:api_url]
33
+ @api_key = connection_config[:api_key]
34
+
35
+ response = Outhad::Integrations::Core::HttpClient.request(
36
+ "#{@api_url}/collections",
37
+ HTTP_GET,
38
+ headers: auth_headers(@api_key)
39
+ )
40
+
41
+ data = JSON.parse(response.body)
42
+ catalog = build_catalog(data)
43
+ catalog.to_outhad_message
44
+ rescue StandardError => e
45
+ handle_exception(e, {
46
+ context: "QDRANT:DISCOVER:EXCEPTION",
47
+ type: "error"
48
+ })
49
+ end
50
+
51
+ def write(sync_config, records, _action = "upsert")
52
+ connection_config = sync_config.destination.connection_specification.with_indifferent_access
53
+ collection_name = sync_config.stream.name
54
+ primary_key = sync_config.model.primary_key
55
+ log_message_array = []
56
+
57
+ api_url = connection_config[:api_url]
58
+ api_key = connection_config[:api_key]
59
+
60
+ write_success = 0
61
+ write_failure = 0
62
+ records.each do |record|
63
+ points = []
64
+ points.push({
65
+ id: record[primary_key],
66
+ vector: JSON.parse(record["vector"]),
67
+ payload: record["payload"]
68
+ })
69
+ begin
70
+ response = upsert_points(api_url, api_key, collection_name, { points: points })
71
+ if success?(response)
72
+ write_success += 1
73
+ log_message_array << log_request_response("info", { points: points }, JSON.parse(response.body))
74
+ else
75
+ # write_failure could be duplicated if JSON.parse errors.
76
+ write_failure += 1
77
+ log_message_array << log_request_response("error", { points: points }, JSON.parse(response.body))
78
+ end
79
+ rescue StandardError => e
80
+ handle_exception(e, {
81
+ context: "QDRANT:RECORD:WRITE:EXCEPTION",
82
+ type: "error",
83
+ sync_id: sync_config.sync_id,
84
+ sync_run_id: sync_config.sync_run_id
85
+ })
86
+ write_failure += 1
87
+ log_message_array << log_request_response("error", { points: points }, e.message)
88
+ end
89
+ end
90
+ tracking_message(write_success, write_failure, log_message_array)
91
+ rescue StandardError => e
92
+ handle_exception(e, {
93
+ context: "QDRANT:RECORD:WRITE:EXCEPTION",
94
+ type: "error",
95
+ sync_id: sync_config.sync_id,
96
+ sync_run_id: sync_config.sync_run_id
97
+ })
98
+ end
99
+
100
+ private
101
+
102
+ def upsert_points(api_url, api_key, collection_name, payload)
103
+ Outhad::Integrations::Core::HttpClient.request(
104
+ api_url + "/collections/#{collection_name}/points",
105
+ HTTP_PUT,
106
+ payload: payload,
107
+ headers: auth_headers(api_key)
108
+ )
109
+ end
110
+
111
+ def build_catalog(data)
112
+ streams = data["result"]["collections"].map { |collection| build_stream(collection) }
113
+ Outhad::Integrations::Protocol::Catalog.new(
114
+ streams: streams,
115
+ request_rate_limit: 60,
116
+ request_rate_limit_unit: "minute",
117
+ request_rate_concurrency: 10
118
+ )
119
+ end
120
+
121
+ def build_stream(collection)
122
+ response = Outhad::Integrations::Core::HttpClient.request(
123
+ "#{@api_url}/collections/#{collection["name"]}",
124
+ HTTP_GET,
125
+ headers: auth_headers(@api_key)
126
+ )
127
+
128
+ payload = { "type" => "object", "properties" => {} }
129
+ if success?(response)
130
+ data = JSON.parse(response.body)
131
+ payload_schema = data["result"]["payload_schema"]
132
+ payload_schema.each { |key, value| payload["properties"][key] = map_qdrant_types(value) } unless payload_schema.empty?
133
+ end
134
+
135
+ Outhad::Integrations::Protocol::Stream.new(
136
+ name: collection["name"],
137
+ action: "update",
138
+ method: HTTP_PUT,
139
+ supported_sync_modes: %w[incremental],
140
+ json_schema: {
141
+ "type" => "object",
142
+ "required" => %w[id vector payload],
143
+ "properties" => {
144
+ "id" => {
145
+ "type" => "string"
146
+ },
147
+ "payload" => payload,
148
+ "vector" => {
149
+ "type" => "vector"
150
+ }
151
+ }
152
+ }
153
+ )
154
+ end
155
+
156
+ def map_qdrant_types(value)
157
+ case value["data_type"]
158
+ when "integer"
159
+ { "type" => "integer" }
160
+ when "float"
161
+ { "type" => "number" }
162
+ when "bool"
163
+ { "type" => "boolean" }
164
+ when "geo"
165
+ {
166
+ "type" => "object",
167
+ "required" => %w[lon lat],
168
+ "properties" => {
169
+ "lon" => {
170
+ "type" => "number"
171
+ },
172
+ "lat" => {
173
+ "type" => "number"
174
+ }
175
+ }
176
+ }
177
+ else
178
+ # datetime, keyword, text, uuid
179
+ { "type" => "string" }
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,15 @@
1
+ {
2
+ "data": {
3
+ "name": "Qdrant",
4
+ "title": "Qdrant",
5
+ "connector_type": "destination",
6
+ "category": "Database",
7
+ "documentation_url": "https://docs.squared.ai/guides/destinations/retl-destinations/database/qdrant",
8
+ "github_issue_label": "destination-qdrant",
9
+ "icon": "icon.svg",
10
+ "license": "MIT",
11
+ "release_stage": "alpha",
12
+ "support_level": "community",
13
+ "tags": ["language:ruby", "outhad"]
14
+ }
15
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "documentation_url": "https://docs.squared.ai/guides/destinations/retl-destinations/database/qdrant",
3
+ "stream_type": "dynamic",
4
+ "connection_specification": {
5
+ "$schema": "http://json-schema.org/draft-07/schema#",
6
+ "title": "Qdrant",
7
+ "type": "object",
8
+ "required": ["api_url", "api_key"],
9
+ "properties": {
10
+ "api_url": {
11
+ "type": "string",
12
+ "title": "API Url",
13
+ "order": 0
14
+ },
15
+ "api_key": {
16
+ "type": "string",
17
+ "outhad_secret": true,
18
+ "title": "API Key",
19
+ "order": 1
20
+ }
21
+ }
22
+ }
23
+ }