diff --git a/src/db.rs b/src/db.rs index d1c5ba71..935d1b7d 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,4 +1,6 @@ use std::error::Error; +use std::collections::HashMap; + use iron::typemap::Key; use iron::prelude::{Plugin, Request}; use persistent::Read; @@ -42,3 +44,44 @@ pub fn get_tile(conn: PostgresPooledConnection, schema: &str, table: &str, z: &s let tile = rows.get(0).get("st_asmvt"); Ok(tile) } + +#[derive(Debug)] +pub struct Tileset { + pub schema: String, + pub table: String, + pub geometry_column: String, + pub srid: i32, + pub _type: String +} + +pub struct Tilesets; +impl Key for Tilesets { type Value = HashMap; } + +pub fn get_tilesets(conn: PostgresPooledConnection) -> Result, Box> { + let query = " + select + f_table_schema, f_table_name, f_geometry_column, srid, type + from geometry_columns + "; + + let mut tilesets = HashMap::new(); + let rows = try!(conn.query(&query, &[])); + + for row in &rows { + let schema = row.get("f_table_schema"); + let table = row.get("f_table_name"); + let id = format!("{}.{}", schema, table); + + let tileset = Tileset { + schema: schema, + table: table, + geometry_column: row.get("f_geometry_column"), + srid: row.get("srid"), + _type: row.get("type") + }; + + tilesets.insert(id, tileset); + } + + Ok(tilesets) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 933241fc..81d7119f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,13 @@ fn main() { println!("Connecting to postgres: {}", conn_string); match db::setup_connection_pool(&conn_string, 10) { - Ok(pool) => chain.link(Read::::both(pool)), + Ok(pool) => { + let conn = pool.get().unwrap(); + let tilesets = db::get_tilesets(conn).unwrap(); + chain.link(Read::::both(tilesets)); + + chain.link(Read::::both(pool)); + }, Err(error) => { eprintln!("Error connectiong to postgres: {}", error); std::process::exit(-1); diff --git a/src/router.rs b/src/router.rs index ffe0422e..084cfa21 100644 --- a/src/router.rs +++ b/src/router.rs @@ -1,6 +1,8 @@ use url::Url; use regex::{Regex, Captures}; +use iron::prelude::{Plugin}; use iron::{status, mime, Request, Response, IronResult}; +use persistent::Read; use super::db; @@ -38,6 +40,12 @@ fn tileset(_req: &mut Request, _caps: Captures) -> IronResult { } fn tile(req: &mut Request, caps: Captures) -> IronResult { + let tilesets = req.get::>().unwrap(); + let tileset = match tilesets.get(&caps["tileset"]) { + Some(tileset) => tileset, + None => return Ok(Response::with((status::NotFound))) + }; + let conn = match db::get_connection(req) { Ok(conn) => conn, Err(error) => { @@ -46,8 +54,7 @@ fn tile(req: &mut Request, caps: Captures) -> IronResult { } }; - - let tile = match db::get_tile(conn, &caps["schema"], &caps["table"], &caps["z"], &caps["x"], &caps["y"]) { + let tile = match db::get_tile(conn, &tileset.schema, &tileset.table, &caps["z"], &caps["x"], &caps["y"]) { Ok(tile) => tile, Err(error) => { eprintln!("Couldn't get a tile: {}", error);