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


##########
c/driver_manager/adbc_driver_manager.cc:
##########
@@ -114,7 +128,175 @@ struct OwnedError {
   }
 };
 
+std::filesystem::path UserConfigDir() {
+  std::filesystem::path config_dir;
+#if defined(_WIN32)
+  auto dir = std::getenv("AppData");
+  if (dir) {
+    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);
+    }
+  } else {
+    config_dir = std::filesystem::path(dir);
+  }
+
+  if (!config_dir.empty()) {
+    config_dir /= "adbc";
+  }
+#endif
+
+  return config_dir;
+}
+
 // Driver state
+struct DriverInfo {
+  std::string manifest_file;
+  std::string driver_name;
+  std::string lib_path;
+  std::string entrypoint;
+
+  std::string version;
+  std::string source;
+};
+
+#ifdef _WIN32
+class RegistryKey {
+ public:
+  RegistryKey(HKEY root, const std::string_view subkey) noexcept
+      : root_(root), key_(nullptr), is_open_(false) {
+    auto result = RegOpenKeyExA(root_, subkey.data(), 0, KEY_READ, &key_);
+    if (result == ERROR_SUCCESS) {
+      is_open_ = true;
+    }
+  }
+
+  ~RegistryKey() {
+    if (is_open_ && key_ != nullptr) {
+      RegCloseKey(key_);
+      key_ = nullptr;
+      is_open_ = false;
+    }
+  }
+
+  HKEY key() const { return key_; }
+  bool is_open() const { return is_open_; }
+
+  std::string GetString(const std::string& name, const std::string& 
default_value = "") {
+    if (!is_open_) return default_value;
+
+    DWORD type = REG_SZ;
+    DWORD size = 0;
+    auto result = RegQueryValueExA(key_, name.c_str(), nullptr, &type, 
nullptr, &size);
+    if (result != ERROR_SUCCESS) return default_value;
+    if (type != REG_SZ) return default_value;
+
+    std::string value(size, '\0');
+    result = RegQueryValueExA(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_;
+  bool is_open_;
+};
+
+AdbcStatusCode LoadDriverFromRegistry(HKEY root, const std::string& 
driver_name,
+                                      DriverInfo& info, struct AdbcError* 
error) {
+  static const LPCSTR kAdbcDriverRegistry = "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 = dkey.GetString("name");
+  info.entrypoint = dkey.GetString("entrypoint");
+  info.version = dkey.GetString("version");
+  info.source = dkey.GetString("source");
+  info.lib_path = dkey.GetString("driver");
+  if (info.lib_path.empty()) {
+    SetError(error, "Driver path not found in registry");
+    return ADBC_STATUS_NOT_FOUND;
+  }
+  return ADBC_STATUS_OK;
+}
+#endif
+
+AdbcStatusCode LoadDriverManifest(const std::filesystem::path& driver_manifest,
+                                  DriverInfo& info, struct AdbcError* error) {
+  toml::table config;
+  try {
+    config = toml::parse_file(driver_manifest.native());
+  } catch (const toml::parse_error& err) {
+    SetError(error, err.what());
+    return ADBC_STATUS_INVALID_STATE;
+  }
+
+  info.manifest_file = driver_manifest.string();
+  info.driver_name = config["name"].value_or(""s);
+  info.entrypoint = config["entrypoint"].value_or(""s);
+  info.version = config["version"].value_or(""s);
+  info.source = config["source"].value_or(""s);
+  auto lib = config.at_path("Driver.shared").value<std::string>();
+  if (!lib) {
+    SetError(error, "Driver path not found in manifest");
+    return ADBC_STATUS_NOT_FOUND;
+  }
+  info.lib_path = lib.value();
+
+  return ADBC_STATUS_OK;
+}
+
+std::vector<std::filesystem::path> GetSearchPaths(const uint16_t levels) {
+  std::vector<std::filesystem::path> paths;
+  if (levels & static_cast<uint16_t>(kAdbcSearchEnvironment)) {
+    // Check the ADBC_DRIVER_PATH environment variable
+    const char* env_path = std::getenv("ADBC_CONFIG_PATH");

Review Comment:
   Fixed



##########
c/driver_manager/adbc_driver_manager.cc:
##########
@@ -114,7 +128,175 @@ struct OwnedError {
   }
 };
 
+std::filesystem::path UserConfigDir() {
+  std::filesystem::path config_dir;
+#if defined(_WIN32)
+  auto dir = std::getenv("AppData");
+  if (dir) {
+    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);
+    }
+  } else {
+    config_dir = std::filesystem::path(dir);
+  }
+
+  if (!config_dir.empty()) {
+    config_dir /= "adbc";
+  }
+#endif
+
+  return config_dir;
+}
+
 // Driver state
+struct DriverInfo {
+  std::string manifest_file;
+  std::string driver_name;
+  std::string lib_path;
+  std::string entrypoint;
+
+  std::string version;
+  std::string source;
+};
+
+#ifdef _WIN32
+class RegistryKey {
+ public:
+  RegistryKey(HKEY root, const std::string_view subkey) noexcept
+      : root_(root), key_(nullptr), is_open_(false) {
+    auto result = RegOpenKeyExA(root_, subkey.data(), 0, KEY_READ, &key_);
+    if (result == ERROR_SUCCESS) {
+      is_open_ = true;
+    }
+  }
+
+  ~RegistryKey() {
+    if (is_open_ && key_ != nullptr) {
+      RegCloseKey(key_);
+      key_ = nullptr;
+      is_open_ = false;
+    }
+  }
+
+  HKEY key() const { return key_; }
+  bool is_open() const { return is_open_; }
+
+  std::string GetString(const std::string& name, const std::string& 
default_value = "") {
+    if (!is_open_) return default_value;
+
+    DWORD type = REG_SZ;
+    DWORD size = 0;
+    auto result = RegQueryValueExA(key_, name.c_str(), nullptr, &type, 
nullptr, &size);
+    if (result != ERROR_SUCCESS) return default_value;
+    if (type != REG_SZ) return default_value;
+
+    std::string value(size, '\0');
+    result = RegQueryValueExA(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_;
+  bool is_open_;
+};
+
+AdbcStatusCode LoadDriverFromRegistry(HKEY root, const std::string& 
driver_name,
+                                      DriverInfo& info, struct AdbcError* 
error) {
+  static const LPCSTR kAdbcDriverRegistry = "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 = dkey.GetString("name");
+  info.entrypoint = dkey.GetString("entrypoint");
+  info.version = dkey.GetString("version");
+  info.source = dkey.GetString("source");
+  info.lib_path = dkey.GetString("driver");
+  if (info.lib_path.empty()) {
+    SetError(error, "Driver path not found in registry");
+    return ADBC_STATUS_NOT_FOUND;
+  }
+  return ADBC_STATUS_OK;
+}
+#endif
+
+AdbcStatusCode LoadDriverManifest(const std::filesystem::path& driver_manifest,
+                                  DriverInfo& info, struct AdbcError* error) {
+  toml::table config;
+  try {
+    config = toml::parse_file(driver_manifest.native());
+  } catch (const toml::parse_error& err) {
+    SetError(error, err.what());
+    return ADBC_STATUS_INVALID_STATE;
+  }
+
+  info.manifest_file = driver_manifest.string();
+  info.driver_name = config["name"].value_or(""s);
+  info.entrypoint = config["entrypoint"].value_or(""s);
+  info.version = config["version"].value_or(""s);
+  info.source = config["source"].value_or(""s);
+  auto lib = config.at_path("Driver.shared").value<std::string>();
+  if (!lib) {
+    SetError(error, "Driver path not found in manifest");

Review Comment:
   added



-- 
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