jdbc 0.0.0

Rust bindings to the Java Jdbc.
Documentation
use jni::{
    objects::{AutoLocal, JMethodID, JObject, JValueGen},
    signature::ReturnType,
    sys::jvalue,
    JNIEnv,
};

use crate::{errors::Error, util};

pub struct ResultSetMetaData<'local> {
    inner: AutoLocal<'local, JObject<'local>>,
    get_column_count: JMethodID,
    get_column_name: JMethodID,
    env: JNIEnv<'local>,
}

impl<'local> ResultSetMetaData<'local> {
    pub fn from_ref(env: &mut JNIEnv<'local>, statement: JObject<'local>) -> Result<Self, Error> {
        let statement = AutoLocal::new(statement, env);

        let class = AutoLocal::new(env.find_class("java/sql/ResultSetMetaData")?, &env);
        let get_column_count = env.get_method_id(&class, "getColumnCount", "()I")?;

        let get_column_name =
            env.get_method_id(&class, "getColumnName", "(I)Ljava/lang/String;")?;

        let env = unsafe { env.unsafe_clone() };
        Ok(ResultSetMetaData {
            inner: statement,
            get_column_count,
            get_column_name,
            env,
        })
    }

    pub fn get_column_count(&mut self) -> Result<i32, Error> {
        return util::call::get_int(&mut self.env, &self.inner, &self.get_column_count);
    }

    pub fn get_column_name(&mut self, column: i32) -> Result<String, Error> {
        let name = unsafe {
            self.env.call_method_unchecked(
                &self.inner,
                self.get_column_name,
                ReturnType::Object,
                &[jvalue { i: column }],
            )?
        };
        if let JValueGen::Object(name) = name {
            return util::cast::obj_cast_string(&mut self.env, name);
        }
        return Err(Error::ImpossibleError);
    }

    pub fn get_columns_name(&mut self) -> Result<Vec<String>, Error> {
        let mut columns = Vec::new();
        let count = self.get_column_count()?;
        for i in 1..count + 1 {
            columns.push(self.get_column_name(i)?);
        }
        Ok(columns)
    }
}