zeroshade commented on code in PR #2918:
URL: https://github.com/apache/arrow-adbc/pull/2918#discussion_r2138260068


##########
c/driver_manager/adbc_driver_manager.cc:
##########
@@ -114,7 +127,289 @@ struct OwnedError {
   }
 };
 
+std::filesystem::path UserConfigDir() {
+  std::filesystem::path config_dir;
+#if defined(_WIN32)
+  size_t required_size;
+  _wgetenv_s(&required_size, NULL, 0, L"AppData");
+  if (required_size == 0) {
+    return config_dir;
+  }
+
+  std::wstring app_data_value;
+  app_data_value.resize(required_size);
+  _wgetenv_s(&required_size, app_data_value.data(), required_size, L"AppData");
+  std::filesystem::path dir(app_data_value);
+  if (!dir.empty()) {
+    config_dir = std::filesystem::path(dir);
+    config_dir /= "ADBC/drivers";
+  }
+#elif defined(__APPLE__)
+  auto dir = std::getenv("HOME");
+  if (dir) {
+    config_dir = std::filesystem::path(dir);
+    config_dir /= "Library/Application Support/ADBC";
+  }
+#elif defined(__linux__)
+  auto dir = std::getenv("XDG_CONFIG_HOME");
+  if (!dir) {
+    dir = std::getenv("HOME");
+    if (dir) {
+      config_dir = std::filesystem::path(dir) /= ".config";
+    }
+  } else {
+    config_dir = std::filesystem::path(dir);
+  }
+
+  if (!config_dir.empty()) {
+    config_dir /= "adbc";
+  }
+#endif
+
+  return config_dir;
+}
+
+#ifdef _WIN32
+using char_type = wchar_t;
+
+std::string utf8_encode(const std::wstring& wstr) {
+  if (wstr.empty()) return std::string();
+  int size_needed = WideCharToMultiByte(
+      CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), NULL, 0, NULL, 
NULL);
+  std::string str_to(size_needed, 0);
+  WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), 
&str_to[0],
+                      size_needed, NULL, NULL);
+  return str_to;
+}
+
+std::wstring utf8_decode(const std::string& str) {
+  if (str.empty()) return std::wstring();
+  int size_needed =
+      MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), 
NULL, 0);
+  std::wstring wstr_to(size_needed, 0);
+  MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), 
&wstr_to[0],
+                      size_needed);
+  return wstr_to;
+}
+
+#else
+using char_type = char;
+#endif
+
 // Driver state
+struct DriverInfo {
+  std::string manifest_file;
+  std::string driver_name;
+  std::filesystem::path lib_path;
+  std::string entrypoint;
+
+  std::string version;
+  std::string source;
+};
+
+#ifdef _WIN32
+class RegistryKey {
+ public:
+  RegistryKey(HKEY root, const std::wstring_view subkey) noexcept
+      : root_(root), key_(nullptr) {
+    status_ = RegOpenKeyExW(root_, subkey.data(), 0, KEY_READ, &key_);
+  }
+
+  ~RegistryKey() {
+    if (is_open() && key_ != nullptr) {
+      RegCloseKey(key_);
+      key_ = nullptr;
+      status_ = ERROR_REGISTRY_IO_FAILED;
+    }
+  }
+
+  HKEY key() const { return key_; }
+  bool is_open() const { return status_ == ERROR_SUCCESS; }
+  LSTATUS status() const { return status_; }
+
+  std::wstring GetString(const std::wstring& name, std::wstring default_value) 
{
+    if (!is_open()) return default_value;
+
+    DWORD type = REG_SZ;
+    DWORD size = 0;
+    auto result = RegQueryValueExW(key_, name.c_str(), nullptr, &type, 
nullptr, &size);
+    if (result != ERROR_SUCCESS) return default_value;
+    if (type != REG_SZ) return default_value;
+
+    std::wstring value(size, '\0');
+    result = RegQueryValueExW(key_, name.c_str(), nullptr, &type,
+                              reinterpret_cast<LPBYTE>(value.data()), &size);
+    if (result != ERROR_SUCCESS) return default_value;
+    return value;
+  }
+
+ private:
+  HKEY root_;
+  HKEY key_;
+  LSTATUS status_;
+};
+
+AdbcStatusCode LoadDriverFromRegistry(HKEY root, const std::wstring& 
driver_name,
+                                      DriverInfo& info, struct AdbcError* 
error) {
+  static const LPCWSTR kAdbcDriverRegistry = L"SOFTWARE\\ADBC\\Drivers";
+  RegistryKey drivers_key(root, kAdbcDriverRegistry);
+  if (!drivers_key.is_open()) {
+    return ADBC_STATUS_NOT_FOUND;
+  }
+
+  RegistryKey dkey(drivers_key.key(), driver_name);
+  if (!dkey.is_open()) {
+    return ADBC_STATUS_NOT_FOUND;
+  }
+
+  info.driver_name = utf8_encode(dkey.GetString(L"name", L""));
+  info.entrypoint = utf8_encode(dkey.GetString(L"entrypoint", L""));
+  info.version = utf8_encode(dkey.GetString(L"version", L""));
+  info.source = utf8_encode(dkey.GetString(L"source", L""));
+  info.lib_path = std::filesystem::path(dkey.GetString(L"driver", L""));
+  if (info.lib_path.empty()) {
+    SetError(error, "Driver path not found in registry for \""s +
+                        utf8_encode(driver_name) + "\"");
+    return ADBC_STATUS_NOT_FOUND;
+  }
+  return ADBC_STATUS_OK;
+}
+#endif
+
+const std::string& current_arch() {

Review Comment:
   I'll take a look at theirs and improve this :)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to