dbui-client 0.0.64

WASM web client sources for dbui
use crate::ctx::ClientContext;

use anyhow::Result;
use dbui_core::profile::UserProfile;
use dbui_core::project::ProjectDescription;
use dbui_core::util::NotificationLevel;
use dbui_core::{RequestMessage, ResponseMessage};
use std::sync::RwLock;
use uuid::Uuid;

pub(crate) struct MessageHandler {}

impl MessageHandler {
  pub(crate) fn handle(ctx: &RwLock<ClientContext>, msg: ResponseMessage) -> Result<()> {
    debug!("Message received: {:?}", msg);
    match msg {
      ResponseMessage::Connected {
        connection_id,
        user_id,
        p,
        u,
        b
      } => on_connected(ctx, connection_id, user_id, p, &u, b)?,
      ResponseMessage::Pong { v } => on_pong(v)?,
      ResponseMessage::Notification { level, content } => on_notification(level, content)?,

      // Custom Messages
      ResponseMessage::SqlResponse { result } => on_sql_response(ctx, result)?,
      ResponseMessage::SchemaResponse { schema } => on_schema(ctx, schema)?,
      _ => warn!("Unhandled ResponseMessage [{:?}]", msg)
    };
    Ok(())
  }
}

fn on_pong(v: i64) -> Result<()> {
  let now = js_sys::Date::now() as i64;
  info!("Pong: [{}ms] elapsed", now - v);
  Ok(())
}

fn on_connected(
  ctx: &RwLock<ClientContext>, connection_id: Uuid, user_id: Uuid, p: Box<ProjectDescription>, u: &UserProfile, b: bool
) -> Result<()> {
  {
    let mut c = ctx.write().unwrap();
    c.on_connected(connection_id, user_id, u.clone(), b);
  }
  let c = ctx.read().unwrap();
  c.get_element_by_id("connection-status")?.set_inner_text("Connected!");
  info!(
    "Connected to {} as [{}] for project [{}]",
    dbui_core::APPNAME,
    u.name(),
    p.as_ref().name
  );
  c.send(RequestMessage::RefreshSchema { full: false });
  Ok(())
}

fn on_notification(level: NotificationLevel, content: String) -> Result<()> {
  crate::logging::notify(level, &content);
  Ok(())
}

fn on_sql_response(ctx: &RwLock<ClientContext>, result: dbui_core::database::results::ResultSet) -> Result<()> {
  let template = crate::templates::results::results(&ctx.read().unwrap(), &result)?;
  let c = ctx.read().unwrap();
  c.replace_template(&format!("{}-results", result.ctx()), template)
}

fn on_schema(ctx: &RwLock<ClientContext>, schema: dbui_core::Schema) -> Result<()> {
  let c = ctx.read().unwrap();
  let tables = crate::templates::schema::table_list(schema.tables().iter().map(|t| t.name()).collect());
  let el = c.get_element_by_id("nav-table-count")?;
  el.set_inner_text(&format!("{} ", schema.tables().len()));
  c.replace_template("nav-tables", tables)?;
  let views = crate::templates::schema::view_list(schema.views().iter().map(|v| v.name()).collect());
  let el = c.get_element_by_id("nav-view-count")?;
  el.set_inner_text(&format!("{} ", schema.views().len()));
  c.replace_template("nav-views", views)?;
  Ok(())
}