Logo Search packages:      
Sourcecode: netams version File versions  Download package

st_sql.c

/*************************************************************************
***   Authentication, authorization, accounting + firewalling package
***   Copyright 1998-2002 Anton Vinokurov <anton@netams.com>
***   Copyright 2002-2008 NeTAMS Development Team
***   This code is GPL v3
***   For latest version and more info, visit this project web page
***   located at http://www.netams.com
***
*************************************************************************/
/* $Id: st_sql.c,v 1.90 2009-08-01 09:23:55 anton Exp $ */

#include "netams.h"
#include "st_any.h"

//////////////////////////////////////////////////////////////////////////
#ifdef USE_ORACLE
const char *st_table_name[ST_CONN_TYPES_NUM]={ "", "RAWDATA", "SUMMARY", "MONITOR",
                                          "LOGIN", "QUOTA", "EVENTS", "OIDS",
                                          "BILLING" , "BDATA", "CONFIG" };
#else
const char *st_table_name[ST_CONN_TYPES_NUM]={ "", "raw", "summary", "monitor", "login", "quota", "events", "oids",
            "billing" , "bdata", "config" };
#endif
//////////////////////////////////////////////////////////////////////////
extern struct sql_data my_sql_data;
extern struct sql_data pg_sql_data;
extern struct sql_data ora_sql_data;
//////////////////////////////////////////////////////////////////////////
class SQL_Storage: public Storage {
      public:
            struct sql_data *sql;

            char *hostname;
            char *username;
            char *password;
            char *dbname;
            char *socket;
            unsigned short port;

            char *oids; //filename of temporary oids file
            char *raw;  //filename of temporary raw file
            char *summary; //filename of temporary summary file

            unsigned num_raw;
            unsigned num_summary;
            unsigned num_oids;

            FILE *f_raw;
            FILE *f_summary;
            FILE *f_oids;

            SQL_Storage(storage_type type, u_char id);
            ~SQL_Storage();

            void ShowCfg(struct cli_def *cli, u_char flags);
            int ProcessCfg(struct cli_def *cli, char **argv, int argc, u_char no_flag);
            int StoreMSG(Message *msg);

            void* Open(st_conn_type type);
            void* Check(void *fd);
            int Load(st_conn_type type,
                  void (*FillData)(void *res, void *row, char* (*getRowData)(void*, void* , u_char)));

            int SaveFile(char *filename, st_conn_type type);
            void Close(st_conn_type type);
};
//////////////////////////////////////////////////////////////////////////
Storage* InitSqlStorage(storage_type st_type, u_char instance) {
      return (Storage*)new SQL_Storage(st_type, instance);
}

SQL_Storage::SQL_Storage(storage_type type, u_char id):Storage(type, id) {

      switch(st_type) {
      #if defined(USE_MYSQL)
            case ST_MYSQL:
                  sql=&my_sql_data;
                  break;
      #endif
      #if defined(USE_POSTGRES)
            case ST_POSTGRES:
                  sql=&pg_sql_data;
                  break;
      #endif
      #if defined(USE_ORACLE)
            case ST_ORACLE:
                  sql=&ora_sql_data;
                  break;
      #endif
            default:
                  break;
      }

      username=password=dbname=socket=hostname=NULL;
      port=0;

      raw=summary=oids=NULL;
      num_raw=num_summary=num_oids=0;
      f_raw=f_summary=f_oids=NULL;

      print_to_string(&oids, "storage.%u.oids", instance);
      print_to_string(&raw, "storage.%u.raw", instance);
      print_to_string(&summary, "storage.%u.summary", instance);
}

SQL_Storage::~SQL_Storage() {
      if(username) aFree(username);
      if(password) aFree(password);
      if(dbname)   aFree(dbname);
      if(hostname) aFree(hostname);
      if(socket) aFree(socket);
      if(oids)   aFree(oids);
      if(raw)    aFree(raw);
      if(summary) aFree(summary);
}

int SQL_Storage::ProcessCfg(struct cli_def *cli, char **param, int argc, u_char no_flag) {
      if (STRARG(param[0], "user")) {
            if(username) aFree(username);
            username=set_string(param[1]);
            cli_error(cli, "username is set to %s", username);
      }
      else if (STRARG(param[0], "password")) {
            if(password) aFree(password);
            password=set_string(param[1]);
            cli_error(cli, "password is set to %s", password);
      }
      else if (STRARG(param[0], "host")) {
            if(hostname) aFree(hostname);
            hostname=set_string(param[1]);
            cli_error(cli, "hostname is set to %s", hostname);
        }
      else if (STRARG(param[0], "dbname")) {
            if(dbname) aFree(dbname);
            dbname=set_string(param[1]);
            cli_error(cli, "dbname is set to %s", dbname);
        }
        else if (STRARG(param[0], "socket")) {
            if(socket) aFree(socket);
            socket=set_string(param[1]);
            cli_error(cli, "socket is set to %s", socket);
        }
      else if (STRARG(param[0], "port")) {
            port=strtol(param[1], NULL, 10);
            cli_error(cli, "port is set to %u", port);
        } else
            return CLI_ERROR;

      return CLI_OK;
}

void SQL_Storage::ShowCfg(struct cli_def *cli, u_char flags){
      cli_print(cli, "type %s", db_type_name[st_type]);
      if (socket) cli_print(cli, "socket %s", socket);
      if (hostname) cli_print(cli, "host %s", hostname);
      if (port && port!=sql->default_port) cli_print(cli, "port %u", port);
      if (username) cli_print(cli, "user %s", (flags&CFG_NO_PASSWORDS)?"***":username);
      if (password) cli_print(cli, "password %s", (flags&CFG_NO_PASSWORDS)?"***":password);
      if (dbname) cli_print(cli, "dbname %s", dbname);
}

int SQL_Storage::StoreMSG(Message *msg) {
      Message_Store *smsg=(Message_Store*)msg;

      if(msg==NULL) {
            if(f_raw) {
                  fclose(f_raw);
                  aDebug(DEBUG_STORAGE, "SQL->HDD/raw %u queries\n", num_raw);
                  SaveFile(raw,ST_CONN_RAW);
            }
            if(f_summary) {
                  fclose(f_summary);
                  aDebug(DEBUG_STORAGE, "SQL->HDD/summary %u queries\n", num_summary);
                  SaveFile(summary,ST_CONN_SUMMARY);
            }
            if(f_oids) {
                  fclose(f_oids);
                  aDebug(DEBUG_STORAGE, "SQL->HDD/oids %u queries\n", num_oids);
                  SaveFile(oids,ST_CONN_OIDS);
            }
            num_raw=num_summary=num_oids=0;
            f_raw=f_summary=f_oids=NULL;

            return 1;
      }

      switch (smsg->prefix){
            case 'F':
                  if(!f_raw) {
                        f_raw=fopen(raw,"a");
                        if(!raw) {
                              aLog(D_ERR, "Can't create temporary file %s: %s\n", raw, strerror(errno));
                              return -1;
                        }
                        setlinebuf(f_raw);
                  }
                  fprintf(f_raw, "%u,%u,%lu,%lu,%llu,%llu\n",
                        smsg->netunit, smsg->ap, smsg->data->from, smsg->ts, smsg->data->in, smsg->data->out);
                  num_raw++;
                  break;
            case 'O':
                  if(!f_oids) {
                        f_oids=fopen(oids,"a");
                        if(!oids) {
                              aLog(D_ERR, "Can't create temporary file %s: %s\n", oids, strerror(errno));
                              return -1;
                        }
                        setlinebuf(f_oids);
                  }
                  if(smsg->netunit) {
                        NetUnit *u;
                        u =(NetUnit*)Units->getById(smsg->netunit);
                        if (u) {
                              fprintf(f_oids, "%u,%s\n", smsg->netunit, u->name);
                              num_oids++;
                        }
                  }
                  if(smsg->ap) {
                        Policy *p;
                        p =(Policy*)PolicyL->getById(smsg->ap);
                        if (p) {
                              fprintf(f_oids, "%u,%s\n", smsg->ap, p->name);
                              num_oids++;
                        }
                  }
                  break;
            case 'H':
            case 'D':
            case 'W':
            case 'M':
                  if(!f_summary) {
                        f_summary=fopen(summary,"a");
                        if(!summary) {
                              aLog(D_ERR, "Can't create temporary file %s: %s\n", summary, strerror(errno));
                              return -1;
                        }
                        setlinebuf(f_summary);
                  }
                  fprintf(f_summary, "%c,%u,%u,%lu,%llu,%llu\n",
                        smsg->prefix, smsg->netunit, smsg->ap, smsg->data->from, smsg->data->in, smsg->data->out);
                  num_summary++;
                  break;
      }
      return 1;
}
//////////////////////////////////////////////////////////////////////////
void* SQL_Storage::Open(st_conn_type conn_type){
      void *fd=FD[conn_type];

      if(fd && Check(fd)) {
            aDebug(DEBUG_STORAGE, "%s DB:%u reuse connection to [%s] for %s\n",
                  db_type_name[st_type],
                  instance,
                  dbname?dbname:"netams",
                  st_table_name[conn_type]);

            return fd;
      }

      //pass info to connect
      struct sql_config cfg;
      cfg.hostname=hostname?hostname:(char*)"localhost";
      cfg.username=username?username:(char*)"root";
      cfg.password=password?password:(char*)"";
      cfg.dbname=dbname?dbname:(char*)"netams";
      cfg.port=port?port:sql->default_port;
      cfg.socket=socket?socket:NULL;

      fd=sql->stOpenSql(&cfg, conn_type);

      aDebug(DEBUG_STORAGE, "%s DB:%u opened [%s] for %s\n",
            db_type_name[st_type],
            instance,
            dbname?dbname:"netams",
            st_table_name[conn_type]);

      FD[conn_type]=fd;
      return fd;
}
//////////////////////////////////////////////////////////////////////////
void* SQL_Storage::Check(void *fd) {

      fd=sql->stCheckSql(fd);

      if(fd == NULL) {
            aLog(D_WARN, "%s DB:%u connection to database %s lost\n",
                  db_type_name[st_type],
                  instance,
                  dbname?dbname:"netams");
      }

      return fd;
}
//////////////////////////////////////////////////////////////////////////
void SQL_Storage::Close(st_conn_type conn_type){
      void *fd=FD[conn_type];

      if(!fd) return;

      sql->stCloseSql(fd);

      FD[conn_type]=NULL;
      aDebug(DEBUG_STORAGE, "%s DB:%u closed to database %s table %s\n",
            db_type_name[st_type],
                instance,
                dbname?dbname:"netams",
                st_table_name[conn_type]
        );
}
//////////////////////////////////////////////////////////////////////////
int SQL_Storage::SaveFile(char *filename, st_conn_type conn_type){
      int ret=0;
      struct stat sb;

      bzero(&sb, sizeof(struct stat));
      stat(filename, &sb);

      if(!(sb.st_mode&S_IFREG)) {
            aDebug(DEBUG_STORAGE, "stSaveSql: file %s not exist\n", filename);
            return -1;
      }

      void *fd=Open(conn_type);
      if(!fd) return -1;

      ret=sql->stSaveSql(fd,filename,conn_type);

      if(ret) {
            aDebug(DEBUG_STORAGE, "SQL->HDD/%s %u affected\n", st_table_name[conn_type], ret);
            unlink(filename);
      }
      else
            aLog(D_WARN, "Failed load data into sql for %s try \"debug storage\"\n", st_table_name[conn_type]);

      return ret;
}
//////////////////////////////////////////////////////////////////////////
int SQL_Storage::Load(st_conn_type conn_type,
      void (*FillData)(void *res, void *row, char* (*getRowData)(void*, void* , u_char)))
{
      int res=0;
      void *fd;

      fd=Open(conn_type);
      if(!fd) return -1;

      char query[512];

      switch(conn_type) {
        case ST_CONN_SUMMARY: {
            struct time_counters tc;

            SaveFile(summary, conn_type);

            PrepareTimeCounters(&tc);

            snprintf(query, 254, "SELECT unit_oid, policy_oid, t_from, prefix, bytes_in, bytes_out FROM summary WHERE \
                  (t_from=%lu AND prefix='M' or t_from=%lu AND prefix='W' or \
                  t_from=%lu AND prefix='D' or t_from=%lu AND prefix='H')",
                  (u_long)tc.mt, (u_long)tc.wt, (u_long)tc.dt, (u_long)tc.ht);

            break;
        }
        case ST_CONN_LOGIN:
            snprintf(query, 254, "SELECT * FROM login");
            break;
        case ST_CONN_QUOTA:
            snprintf(query, 254, "SELECT * FROM quota");
            break;
        case ST_CONN_BILLING:
            snprintf(query, 254, "SELECT * FROM billing ORDER BY CREATED");
            break;
        case ST_CONN_BDATA: {
            struct time_counters tc;
            PrepareTimeCounters(&tc);

            snprintf(query, 254, "SELECT account_oid, subplan_oid, t_from, prefix, bytes_in, bytes_out, pay_in, pay_out\
                  FROM bdata WHERE\
                  (t_from=%lu AND prefix='M' or t_from=%lu AND prefix='W' or \
                  t_from=%lu AND prefix='D' or t_from=%lu AND prefix='H')",
                  (u_long)tc.mt, (u_long)tc.wt, (u_long)tc.dt, (u_long)tc.ht);
            break;
        }
        default:
            return -1;
      }
      aDebug(DEBUG_STORAGE, "ObtainDbData query: '%s'\n", query);

//    netams_rwlock_rdlock(&Units->rwlock);
      res=sql->stObtainDbData(fd, query, FillData);
//    netams_rwlock_unlock(&Units->rwlock);

      if(!res) {
            aDebug(DEBUG_STORAGE, "%s DB:%u %s table access problem\n",
                  db_type_name[st_type],
                  instance,
                  st_table_name[conn_type]
            );
      }
      return res;
}
//////////////////////////////////////////////////////////////////////////

Generated by  Doxygen 1.6.0   Back to index