<commit_before>//! Simple client program
//! Establishes connection to server and sends login information
#[macro_use]
extern crate log;
extern crate uosql;
extern crate bincode;
extern crate byteorder;
extern crate docopt;
extern crate rustc_serialize;
extern crate server;
extern crate regex;
extern crate libc;

extern {
    fn key() -> libc::c_int;
}

mod specialcrate;

use std::net::Ipv4Addr;
use std::cmp::{max, min};
use std::fs::File;
use std::error::Error;
use std::io::{self, stdout, Write, Read};
use std::str::FromStr;
use uosql::logger;
use uosql::Connection;
use uosql::types::{DataSet};
use server::storage::SqlType;
use docopt::Docopt;
use regex::Regex;
use bincode::rustc_serialize::{decode_from, encode_into};
use bincode::SizeLimit;

/// For console input, manages flags and arguments
const USAGE: &'static str = "
Usage: uosql-client [--bind=<address>] [--port=<port>] [--name=<username>]
        [--pwd=<password>]

Options:
    --bind=<address>    Change the bind address.
    --port=<port>       Change the port.
    --name=<username>   Login with given username.
    --pwd=<password>    Login with given password.
";

#[derive(Debug, RustcDecodable)]
struct Args {
   flag_bind: Option<String>,
   flag_port: Option<u16>,
   flag_name: Option<String>,
   flag_pwd:  Option<String>
}



fn main() {

    logger::with_loglevel(log::LogLevelFilter::Trace)
        .with_logfile(std::path::Path::new("log.txt"))
        .enable().unwrap();

    // Getting the information for a possible configuration
    let args : Args = Docopt::new(USAGE).and_then(|d| d.decode())
                                        .unwrap_or_else(|e| e.exit());

    // Change the bind address if flag is set
    let address = {
        match args.flag_bind {
            Some(a) => {
                if Ipv4Addr::from_str(&a).is_ok() { a }
                else { read_address() }
            },
            None => {
                read_address()
            }
        }
    };

    // Change port if flag is set
    let port = {
        match args.flag_port {
            Some(p) => {
                if p > 1024 {
                    p
                } else {
                    read_port()
                }
            },
            None => read_port()
        }
    };

    // Set username for connection
    let username = {
        match args.flag_name {
            Some(u) => u,
            None => read_string("Username")
        }
    };

    // Set password for connection
    let password = {
        match args.flag_pwd {
            Some(p) => p,
            None => read_string("Password")
        }
    };

    // Connect to uosql server with given parameters.
    let mut conn = match Connection::connect(address, port, username, password)
    {
        Ok(conn) => conn,
        Err(e) => {
            match e {
                uosql::Error::AddrParse(_) => {
                    error!("{}", e.description());
                    return
                },
                uosql::Error::Io(_) => {
                    error!("{}", e.description());
                    return
                },
                uosql::Error::Decode(_) => {
                    error!("{}", e.description());
                    return
                },
                uosql::Error::Encode(_) => {
                    error!("{}", e.description());
                    return
                },
                uosql::Error::UnexpectedPkg => {
                    error!("{}", e.description());
                    return
                },
                uosql::Error::Auth => {
                    info!("{}", e.description());
                    return
                },
                uosql::Error::Server(_) => {
                    error!("{}", e.description());
                    return
                }
            }
        }
    };

    println!("Connected (version: {}) to {}:{}\n{}\n",
        conn.get_version(), conn.get_ip(), conn.get_port(), conn.get_message());

    // Load history from "uosql_client.history" if possible
    let mut history: Vec<String>;
    let f = File::open("uosql_client.history");
    match f {
        Ok(mut f) => {
            history = match decode_from(&mut f, SizeLimit::Infinite) {
                Ok(his) => { his },
                Err(_) => { println!("Could not read command history."); vec![] }
            }
        },
        Err(_) => {
            history = vec![];
            println!("Could not load command history.");
        }
    };

    // Read commands from user
    loop {
        print!("> ");
        stdout().flush().ok().expect("Could not flush stdout.");

        let mut h_idx = 0;
        let mut input: String = "".into();
        let mut key_pressed = unsafe { key() };
        let mut linelen = 0;

        // Handle Up/Down input to jump in history and execute commands from history
        while h_idx <= history.len() && (key_pressed == 0 || key_pressed == 1 || key_pressed == 13) {
            match key_pressed {
                0 => {
                    if !history.is_empty() && h_idx < history.len() {
                        h_idx += 1;
                        let mut whitespace: String = "".into();
                        for _ in 0..linelen {
                            whitespace.push_str(" ");<commit_msg>Add line break<commit_after>//! Simple client program
//! Establishes connection to server and sends login information
#[macro_use]
extern crate log;
extern crate uosql;
extern crate bincode;
extern crate byteorder;
extern crate docopt;
extern crate rustc_serialize;
extern crate server;
extern crate regex;
extern crate libc;

extern {
    fn key() -> libc::c_int;
}

mod specialcrate;

use std::net::Ipv4Addr;
use std::cmp::{max, min};
use std::fs::File;
use std::error::Error;
use std::io::{self, stdout, Write, Read};
use std::str::FromStr;
use uosql::logger;
use uosql::Connection;
use uosql::types::{DataSet};
use server::storage::SqlType;
use docopt::Docopt;
use regex::Regex;
use bincode::rustc_serialize::{decode_from, encode_into};
use bincode::SizeLimit;

/// For console input, manages flags and arguments
const USAGE: &'static str = "
Usage: uosql-client [--bind=<address>] [--port=<port>] [--name=<username>]
        [--pwd=<password>]

Options:
    --bind=<address>    Change the bind address.
    --port=<port>       Change the port.
    --name=<username>   Login with given username.
    --pwd=<password>    Login with given password.
";

#[derive(Debug, RustcDecodable)]
struct Args {
   flag_bind: Option<String>,
   flag_port: Option<u16>,
   flag_name: Option<String>,
   flag_pwd:  Option<String>
}



fn main() {

    logger::with_loglevel(log::LogLevelFilter::Trace)
        .with_logfile(std::path::Path::new("log.txt"))
        .enable().unwrap();

    // Getting the information for a possible configuration
    let args : Args = Docopt::new(USAGE).and_then(|d| d.decode())
                                        .unwrap_or_else(|e| e.exit());

    // Change the bind address if flag is set
    let address = {
        match args.flag_bind {
            Some(a) => {
                if Ipv4Addr::from_str(&a).is_ok() { a }
                else { read_address() }
            },
            None => {
                read_address()
            }
        }
    };

    // Change port if flag is set
    let port = {
        match args.flag_port {
            Some(p) => {
                if p > 1024 {
                    p
                } else {
                    read_port()
                }
            },
            None => read_port()
        }
    };

    // Set username for connection
    let username = {
        match args.flag_name {
            Some(u) => u,
            None => read_string("Username")
        }
    };

    // Set password for connection
    let password = {
        match args.flag_pwd {
            Some(p) => p,
            None => read_string("Password")
        }
    };

    // Connect to uosql server with given parameters.
    let mut conn = match Connection::connect(address, port, username, password)
    {
        Ok(conn) => conn,
        Err(e) => {
            match e {
                uosql::Error::AddrParse(_) => {
                    error!("{}", e.description());
                    return
                },
                uosql::Error::Io(_) => {
                    error!("{}", e.description());
                    return
                },
                uosql::Error::Decode(_) => {
                    error!("{}", e.description());
                    return
                },
                uosql::Error::Encode(_) => {
                    error!("{}", e.description());
                    return
                },
                uosql::Error::UnexpectedPkg => {
                    error!("{}", e.description());
                    return
                },
                uosql::Error::Auth => {
                    info!("{}", e.description());
                    return
                },
                uosql::Error::Server(_) => {
                    error!("{}", e.description());
                    return
                }
            }
        }
    };

    println!("Connected (version: {}) to {}:{}\n{}\n",
        conn.get_version(), conn.get_ip(), conn.get_port(), conn.get_message());

    // Load history from "uosql_client.history" if possible
    let mut history: Vec<String>;
    let f = File::open("uosql_client.history");
    match f {
        Ok(mut f) => {
            history = match decode_from(&mut f, SizeLimit::Infinite) {
                Ok(his) => { his },
                Err(_) => { println!("Could not read command history."); vec![] }
            }
        },
        Err(_) => {
            history = vec![];
            println!("Could not load command history.");
        }
    };

    // Read commands from user
    loop {
        print!("> ");
        stdout().flush().ok().expect("Could not flush stdout.");

        let mut h_idx = 0;
        let mut input: String = "".into();
        let mut key_pressed = unsafe { key() };
        let mut linelen = 0;

        // Handle Up/Down input to jump in history and execute commands from history
        while h_idx <= history.len() &&
            (key_pressed == 0 || key_pressed == 1 || key_pressed == 13) 
        {
            match key_pressed {
                0 => {
                    if !history.is_empty() && h_idx < history.len() {
                        h_idx += 1;
                        let mut whitespace: String = "".into();
                        for _ in 0..linelen {
                            whitespace.push_str(" ");
{'fraction_non_alphanumeric': 0.14108585384181851, 'fraction_numerical': 0.0031936877700544804, 'mean_word_length': 1.5692567567567568, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5172956', 'n_tokens_mistral': 3072, 'n_tokens_neox': 2936, 'n_words': 746}