Esempio n. 1
0
/*************************************************************************
 *
 *	Function: sql_fetch_row
 *
 *	Purpose: database specific fetch_row. Returns a SQL_ROW struct
 *               with all the data for the query in 'sqlsocket->row'. Returns
 *		 0 on success, -1 on failure, SQL_DOWN if 'database is down'
 *
 *************************************************************************/
static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config) 
{
	int c, i;
	SQLINTEGER len, slen;
	SQL_ROW retval;
	rlm_sql_db2_sock *sock;

	sock = sqlsocket->conn;

	c = sql_num_fields(sqlsocket, config);
	retval = (SQL_ROW)rad_malloc(c*sizeof(char*)+1);
	/* advance cursor */
	if(SQLFetch(sock->stmt) == SQL_NO_DATA_FOUND) {
		sqlsocket->row = NULL;
		return 0;
	}

	for(i = 0; i < c; i++) {
		/* get column length */
		SQLColAttribute(sock->stmt,
				i+1, SQL_DESC_DISPLAY_SIZE,
				NULL, 0, NULL, &len);
		retval[i] = (char*)rad_malloc(len+1);
		/* get the actual column */
		SQLGetData(sock->stmt,
				i+1, SQL_C_CHAR, retval[i], len+1, &slen);
		if(slen == SQL_NULL_DATA)
			retval[i][0] = '\0';
	}

	sqlsocket->row = retval;
	return 0;
}
static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char const *query)
{
	rlm_sql_unixodbc_conn_t *conn = handle->conn;
	SQLINTEGER i;
	SQLLEN len;
	int colcount;
	int state;

	/* Only state = 0 means success */
	if ((state = sql_query(handle, config, query))) {
		return state;
	}

	colcount = sql_num_fields(handle, config);
	if (colcount < 0) {
		return RLM_SQL_ERROR;
	}

	/* Reserving memory for result */
	conn->row = talloc_zero_array(conn, char *, colcount + 1); /* Space for pointers */

	for (i = 1; i <= colcount; i++) {
		SQLColAttributes(conn->statement, ((SQLUSMALLINT) i), SQL_COLUMN_LENGTH, NULL, 0, NULL, &len);
		conn->row[i - 1] = talloc_array(conn->row, char, ++len);
		SQLBindCol(conn->statement, i, SQL_C_CHAR, (SQLCHAR *)conn->row[i - 1], len, NULL);
	}

	return RLM_SQL_OK;
}
/*************************************************************************
 *
 *	Function: sql_select_query
 *
 *	Purpose: Issue a select query to the database
 *
 *************************************************************************/
static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char const *query) {
    rlm_sql_unixodbc_conn_t *conn = handle->conn;
    SQLINTEGER column;
    SQLLEN len;
    int numfields;
    int state;

    /* Only state = 0 means success */
    if ((state = sql_query(handle, config, query))) {
        return state;
    }

    numfields=sql_num_fields(handle, config);
    if (numfields < 0) {
        return -1;
    }

    /* Reserving memory for result */
    conn->row = (char **) rad_malloc((numfields+1)*sizeof(char *));
    conn->row[numfields] = NULL;

    for(column = 1; column <= numfields; column++) {
        SQLColAttributes(conn->statement,((SQLUSMALLINT) column),SQL_COLUMN_LENGTH,NULL,0,NULL,&len);
        conn->row[column-1] = (char*)rad_malloc((int)++len);
        SQLBindCol(conn->statement, column, SQL_C_CHAR, (SQLCHAR *)conn->row[column-1], len, NULL);
    }
    return 0;
}
Esempio n. 4
0
/*************************************************************************
 *
 *	Function: sql_query
 *
 *	Purpose: Issue a query to the database
 *
 *************************************************************************/
static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) {

	rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;

	if (config->sqltrace)
		radlog(L_DBG,"rlm_sql_postgresql: query:\n%s", querystr);

	if (pg_sock->conn == NULL) {
		radlog(L_ERR, "rlm_sql_postgresql: Socket not connected");
		return SQL_DOWN;
	}

	pg_sock->result = PQexec(pg_sock->conn, querystr);
		/* Returns a result pointer or possibly a NULL pointer.
		 * A non-NULL pointer will generally be returned except in
		 * out-of-memory conditions or serious errors such as inability
		 * to send the command to the backend. If a NULL is returned,
		 *  it should be treated like a PGRES_FATAL_ERROR result.
		 * Use PQerrorMessage to get more information about the error.
		 */
	if (!pg_sock->result)
	{
		radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Query failed Error: %s",
				PQerrorMessage(pg_sock->conn));
		return  SQL_DOWN;
	} else {
		ExecStatusType status = PQresultStatus(pg_sock->result);

		radlog(L_DBG, "rlm_sql_postgresql: Status: %s", PQresStatus(status));

		radlog(L_DBG, "rlm_sql_postgresql: affected rows = %s",
				PQcmdTuples(pg_sock->result));

		if (!status_is_ok(status))
			return sql_check_error(status);

		if (strncasecmp("select", querystr, 6) != 0) {
			/* store the number of affected rows because the sql module
			 * calls finish_query before it retrieves the number of affected
			 * rows from the driver */
			pg_sock->affected_rows = affected_rows(pg_sock->result);
			return 0;
		} else {
			if ((sql_store_result(sqlsocket, config) == 0)
					&& (sql_num_fields(sqlsocket, config) >= 0))
				return 0;
			else
				return -1;
		}
	}
}
/*************************************************************************
 *
 *	Function: sql_free_result
 *
 *	Purpose: database specific free_result. Frees memory allocated
 *	       for a result set
 *
 *************************************************************************/
static sql_rcode_t sql_free_result(rlm_sql_handle_t *handle, rlm_sql_config_t *config) {

	int i=0;
	rlm_sql_iodbc_conn_t *conn = handle->conn;

	for(i=0; i<sql_num_fields(handle, config); i++) {
		free(conn->row[i]);
	}
	free(conn->row);
	conn->row=NULL;

	SQLFreeStmt( conn->stmt_handle, SQL_DROP );

	return 0;
}
Esempio n. 6
0
/*************************************************************************
 *
 *	Function: sql_num_fields
 *
 *	Purpose: database specific num_fields function. Returns number
 *               of columns from query
 *
 *************************************************************************/
static int sql_num_fields(SQLSOCK * sqlsocket, UNUSED SQL_CONFIG *config)
{
	int     num = 0;
	rlm_sql_mysql_sock *mysql_sock = sqlsocket->conn;

#if MYSQL_VERSION_ID >= 32224
	if (!(num = mysql_field_count(mysql_sock->sock))) {
#else
	if (!(num = mysql_num_fields(mysql_sock->sock))) {
#endif
		radlog(L_ERR, "rlm_sql_mysql: MYSQL Error: No Fields");
		radlog(L_ERR, "rlm_sql_mysql: MYSQL error: %s",
		       mysql_error(mysql_sock->sock));
	}
	return num;
}


/*************************************************************************
 *
 *	Function: sql_select_query
 *
 *	Purpose: Issue a select query to the database
 *
 *************************************************************************/
static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config,
			    char *querystr)
{
	int ret;

	ret = sql_query(sqlsocket, config, querystr);
	if(ret)
		return ret;
	ret = sql_store_result(sqlsocket, config);
	if (ret) {
		return ret;
	}

	/* Why? Per http://www.mysql.com/doc/n/o/node_591.html,
	 * this cannot return an error.  Perhaps just to complain if no
	 * fields are found?
	 */
	sql_num_fields(sqlsocket, config);

	return ret;
}
/*************************************************************************
 *
 *	Function: sql_free_result
 *
 *	Purpose: database specific free_result. Frees memory allocated
 *               for a result set
 *
 *************************************************************************/
static int sql_free_result(rlm_sql_handle_t *handle, rlm_sql_config_t *config) {
    rlm_sql_unixodbc_sock *unixodbc_sock = handle->conn;
    int column, numfileds=sql_num_fields(handle, config);

    /* Freeing reserved memory */
    if(unixodbc_sock->row != NULL) {
	for(column=0; column<numfileds; column++) {
	    if(unixodbc_sock->row[column] != NULL) {
		free(unixodbc_sock->row[column]);
		unixodbc_sock->row[column] = NULL;
	    }
	}
        free(unixodbc_sock->row);
	unixodbc_sock->row = NULL;
    }
    return 0;
}
/*************************************************************************
 *
 *	Function: sql_num_fields
 *
 *	Purpose: database specific num_fields function. Returns number
 *	       of columns from query
 *
 *************************************************************************/
static int sql_num_fields(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config)
{
	int     num = 0;
	rlm_sql_mysql_conn_t *conn = handle->conn;

#if MYSQL_VERSION_ID >= 32224
	if (!(num = mysql_field_count(conn->sock))) {
#else
	if (!(num = mysql_num_fields(conn->sock))) {
#endif
		ERROR("rlm_sql_mysql: MYSQL Error: No Fields");
		ERROR("rlm_sql_mysql: MYSQL error: %s",
		       mysql_error(conn->sock));
	}
	return num;
}


/*************************************************************************
 *
 *	Function: sql_select_query
 *
 *	Purpose: Issue a select query to the database
 *
 *************************************************************************/
static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char const *query)
{
	int ret;

	ret = sql_query(handle, config, query);
	if(ret)
		return ret;
	ret = sql_store_result(handle, config);
	if (ret) {
		return ret;
	}

	/* Why? Per http://www.mysql.com/doc/n/o/node_591.html,
	 * this cannot return an error.  Perhaps just to complain if no
	 * fields are found?
	 */
	sql_num_fields(handle, config);

	return ret;
}
Esempio n. 9
0
/*************************************************************************
 *
 *	Function: sql_fetch_row
 *
 *	Purpose: database specific fetch_row. Returns a rlm_sql_row_t struct
 *	       with all the data for the query in 'handle->row'. Returns
 *		 0 on success, -1 on failure, RLM_SQL_RECONNECT if 'database is down'
 *
 *************************************************************************/
static sql_rcode_t sql_fetch_row(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
{
	int c, i;
	SQLINTEGER len, slen;
	rlm_sql_row_t retval;
	rlm_sql_db2_conn_t *conn;

	conn = handle->conn;

	c = sql_num_fields(handle, config);
	retval = (rlm_sql_row_t)rad_malloc(c*sizeof(char*)+1);
	memset(retval, 0, c*sizeof(char*)+1);

	/* advance cursor */
	if(SQLFetch(conn->stmt) == SQL_NO_DATA_FOUND) {
		handle->row = NULL;
		goto error;
	}

	for(i = 0; i < c; i++) {
		/* get column length */
		SQLColAttribute(conn->stmt, i+1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &len);
		
		retval[i] = rad_malloc(len+1);
		
		/* get the actual column */
		SQLGetData(conn->stmt, i + 1, SQL_C_CHAR, retval[i], len+1, &slen);
		if(slen == SQL_NULL_DATA) {
			retval[i][0] = '\0';
		}
	}

	handle->row = retval;
	return RLM_SQL_OK;

error:
	for(i = 0; i < c; i++) {
		free(retval[i]);
	}
	free(retval);
	
	return RLM_SQL_ERROR;
}
Esempio n. 10
0
/*************************************************************************
 *
 *	Function: sql_select_query
 *
 *	Purpose: Issue a select query to the database
 *
 *************************************************************************/
static sql_rcode_t sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char const *query) {

	int numfields = 0;
	int i = 0;
	char **row = NULL;
	long len = 0;
	rlm_sql_iodbc_conn_t *conn = handle->conn;

	if(sql_query(handle, config, query) < 0) {
		return -1;
	}

	numfields = sql_num_fields(handle, config);

	row = (char **) rad_malloc(sizeof(char *) * (numfields+1));
	memset(row, 0, (sizeof(char *) * (numfields)));
	row[numfields] = NULL;

	for(i=1; i<=numfields; i++) {
		SQLColAttributes(conn->stmt_handle, ((SQLUSMALLINT) i), SQL_COLUMN_LENGTH, NULL, 0, NULL, &len);
		len++;

		/*
		 * Allocate space for each column
		 */
		row[i - 1] = rad_malloc((size_t) len);

		/*
		 * This makes me feel dirty, but, according to Microsoft, it works.
		 * Any ODBC datatype can be converted to a 'char *' according to
		 * the following:
		 *
		 * http://msdn.microsoft.com/library/psdk/dasdk/odap4o4z.htm
		 */
		SQLBindCol(conn->stmt_handle, i, SQL_C_CHAR, (SQLCHAR *)row[i-1], len, 0);
	}

	conn->row = row;

	return 0;
}
Esempio n. 11
0
File: sql.c Progetto: debfx/bareos
/*
 * List dashes as part of header for listing SQL results in a table
 */
static void list_dashes(B_DB *mdb, OUTPUT_FORMATTER *send)
{
   SQL_FIELD *field;
   int i, j;
   int len;
   int num_fields;

   sql_field_seek(mdb, 0);
   send->decoration("+");
   num_fields = sql_num_fields(mdb);
   for (i = 0; i < num_fields; i++) {
      field = sql_fetch_field(mdb);
      if (!field) {
         break;
      }
      len = max_length(field->max_length + 2);
      for (j = 0; j < len; j++) {
         send->decoration("-");
      }
      send->decoration("+");
   }
   send->decoration("\n");
}
Esempio n. 12
0
/*
 * List dashes as part of header for listing SQL results in a table
 */
void list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx)
{
   SQL_FIELD *field;
   int i, j;
   int len;
   int num_fields;

   sql_field_seek(mdb, 0);
   send(ctx, "+");
   num_fields = sql_num_fields(mdb);
   for (i = 0; i < num_fields; i++) {
      field = sql_fetch_field(mdb);
      if (!field) {
         break;
      }
      len = max_length(field->max_length + 2);
      for (j = 0; j < len; j++) {
         send(ctx, "-");
      }
      send(ctx, "+");
   }
   send(ctx, "\n");
}
Esempio n. 13
0
File: sql.c Progetto: debfx/bareos
/*
 * If full_list is set, we list vertically, otherwise, we
 *  list on one line horizontally.
 * Return number of rows
 */
int list_result(JCR *jcr, B_DB *mdb, OUTPUT_FORMATTER *send, e_list_type type)
{
   SQL_FIELD *field;
   SQL_ROW row;
   int i, col_len, max_len = 0;
   int num_fields;
   char ewc[30];
   POOL_MEM key;
   POOL_MEM value;

   Dmsg0(800, "list_result starts\n");
   if (sql_num_rows(mdb) == 0) {
      send->decoration(_("No results to list.\n"));
      send->object_end("table");
      return sql_num_rows(mdb);
   }

   num_fields = sql_num_fields(mdb);
   switch (type) {
   case NF_LIST:
   case RAW_LIST:
      /*
       * No need to calculate things like column widths for
       * unformated or raw output.
       */
      break;
   case HORZ_LIST:
   case VERT_LIST:
      Dmsg1(800, "list_result starts looking at %d fields\n", num_fields);
      /*
       * Determine column display widths
       */
      sql_field_seek(mdb, 0);
      for (i = 0; i < num_fields; i++) {
         Dmsg1(800, "list_result processing field %d\n", i);
         field = sql_fetch_field(mdb);
         if (!field) {
            break;
         }
         col_len = cstrlen(field->name);
         if (type == VERT_LIST) {
            if (col_len > max_len) {
               max_len = col_len;
            }
         } else {
            if (sql_field_is_numeric(mdb, field->type) && (int)field->max_length > 0) { /* fixup for commas */
               field->max_length += (field->max_length - 1) / 3;
            }
            if (col_len < (int)field->max_length) {
               col_len = field->max_length;
            }
            if (col_len < 4 && !sql_field_is_not_null(mdb, field->flags)) {
               col_len = 4;                 /* 4 = length of the word "NULL" */
            }
            field->max_length = col_len;    /* reset column info */
         }
      }
      break;
   }

   Dmsg0(800, "list_result finished first loop\n");

   switch (type) {
   case NF_LIST:
   case RAW_LIST:
      Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields);
      while ((row = sql_fetch_row(mdb)) != NULL) {
         send->object_start(row[0]);
         sql_field_seek(mdb, 0);
         for (i = 0; i < num_fields; i++) {
            field = sql_fetch_field(mdb);
            if (!field) {
               break;
            }
            if (row[i] == NULL) {
               value.bsprintf(" %s", "NULL");
            } else {
               value.bsprintf(" %s", row[i]);
            }
            send->object_key_value(field->name, value.c_str(), "%s");
         }
         if (type != RAW_LIST) {
            send->decoration("\n");
         }
         send->object_end(row[0]);
      }
      break;
   case HORZ_LIST:
      Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields);
      list_dashes(mdb, send);
      send->decoration("|");
      sql_field_seek(mdb, 0);
      for (i = 0; i < num_fields; i++) {
         Dmsg1(800, "list_result looking at field %d\n", i);
         field = sql_fetch_field(mdb);
         if (!field) {
            break;
         }
         max_len = max_length(field->max_length);
         send->decoration(" %-*s |", max_len, field->name);
      }
      send->decoration("\n");
      list_dashes(mdb, send);

      Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields);
      while ((row = sql_fetch_row(mdb)) != NULL) {
         send->object_start(row[0]);
         sql_field_seek(mdb, 0);
         send->decoration("|");
         for (i = 0; i < num_fields; i++) {
            field = sql_fetch_field(mdb);
            if (!field) {
               break;
            }
            max_len = max_length(field->max_length);
            if (row[i] == NULL) {
               value.bsprintf(" %-*s |", max_len, "NULL");
            } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) {
               value.bsprintf(" %*s |", max_len, add_commas(row[i], ewc));
            } else {
               value.bsprintf(" %-*s |", max_len, row[i]);
            }
            if (i == num_fields-1) {
               value.strcat("\n");
            }
            /* use value format string to send preformated value */
            send->object_key_value(field->name, row[i], value.c_str());
         }
         send->object_end(row[0]);
      }
      list_dashes(mdb, send);
      break;
   case VERT_LIST:
      Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields);
      while ((row = sql_fetch_row(mdb)) != NULL) {
         send->object_start(row[0]);
         sql_field_seek(mdb, 0);
         for (i = 0; i < num_fields; i++) {
            field = sql_fetch_field(mdb);
            if (!field) {
               break;
            }
            if (row[i] == NULL) {
               key.bsprintf(" %*s: ", max_len, field->name);
               value.bsprintf("%s\n", "NULL");
            } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) {
               key.bsprintf(" %*s: ", max_len, field->name);
               value.bsprintf("%s\n", add_commas(row[i], ewc));
            } else {
               key.bsprintf(" %*s: ", max_len, field->name);
               value.bsprintf("%s\n", row[i]);
            }
            /* use value format string to send preformated value */
            send->object_key_value(field->name, key.c_str(), row[i], value.c_str());
         }
         send->decoration("\n");
         send->object_end(row[0]);
      }
      break;
   }
   return sql_num_rows(mdb);
}
Esempio n. 14
0
File: sql.c Progetto: debfx/bareos
int list_result(void *vctx, int nb_col, char **row)
{
   SQL_FIELD *field;
   int i, col_len, max_len = 0;
   int num_fields;
   char ewc[30];
   POOL_MEM key;
   POOL_MEM value;

   LIST_CTX *pctx = (LIST_CTX *)vctx;
   OUTPUT_FORMATTER *send = pctx->send;
   e_list_type type = pctx->type;
   B_DB *mdb = pctx->mdb;
   JCR *jcr = pctx->jcr;

   send->object_start("row");

   num_fields = sql_num_fields(mdb);
   switch (type) {
   case NF_LIST:
   case RAW_LIST:
      /*
       * No need to calculate things like maximum field lenght for
       * unformated or raw output.
       */
      break;
   case HORZ_LIST:
   case VERT_LIST:
      if (!pctx->once) {
         pctx->once = true;

         Dmsg1(800, "list_result starts looking at %d fields\n", num_fields);
         /*
          * Determine column display widths
          */
         sql_field_seek(mdb, 0);
         for (i = 0; i < num_fields; i++) {
            Dmsg1(800, "list_result processing field %d\n", i);
            field = sql_fetch_field(mdb);
            if (!field) {
               break;
            }
            col_len = cstrlen(field->name);
            if (type == VERT_LIST) {
               if (col_len > max_len) {
                  max_len = col_len;
               }
            } else {
               if (sql_field_is_numeric(mdb, field->type) && (int)field->max_length > 0) { /* fixup for commas */
                  field->max_length += (field->max_length - 1) / 3;
               }
               if (col_len < (int)field->max_length) {
                  col_len = field->max_length;
               }
               if (col_len < 4 && !sql_field_is_not_null(mdb, field->flags)) {
                  col_len = 4;                 /* 4 = length of the word "NULL" */
               }
               field->max_length = col_len;    /* reset column info */
            }
         }

         pctx->num_rows++;

         Dmsg0(800, "list_result finished first loop\n");
         if (type == VERT_LIST) {
            break;
         }

         Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields);

         /*
          * Keep the result to display the same line at the end of the table
          */
         list_dashes(mdb, send);

         send->decoration("|");
         sql_field_seek(mdb, 0);
         for (i = 0; i < num_fields; i++) {
            Dmsg1(800, "list_result looking at field %d\n", i);
            field = sql_fetch_field(mdb);
            if (!field) {
               break;
            }
            max_len = max_length(field->max_length);
            send->decoration(" %-*s |", max_len, field->name);
         }
         send->decoration("\n");
         list_dashes(mdb, send);
      }
      break;
   default:
      break;
   }

   switch (type) {
   case NF_LIST:
   case RAW_LIST:
      Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields);
      sql_field_seek(mdb, 0);
      for (i = 0; i < num_fields; i++) {
         field = sql_fetch_field(mdb);
         if (!field) {
            break;
         }
         if (row[i] == NULL) {
            value.bsprintf(" %s", "NULL");
         } else {
            value.bsprintf(" %s", row[i]);
         }
         send->object_key_value(field->name, value.c_str(), "%s");
      }
      if (type != RAW_LIST) {
         send->decoration("\n");
      }
      break;
   case HORZ_LIST:
      Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields);
      sql_field_seek(mdb, 0);
      send->decoration("|");
      for (i = 0; i < num_fields; i++) {
         field = sql_fetch_field(mdb);
         if (!field) {
            break;
         }

         max_len = max_length(field->max_length);
         if (row[i] == NULL) {
            value.bsprintf(" %-*s |", max_len, "NULL");
         } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) {
            value.bsprintf(" %*s |", max_len, add_commas(row[i], ewc));
         } else {
            value.bsprintf(" %-*s |", max_len, row[i]);
         }

         /*
          * Use value format string to send preformated value.
          */
         send->object_key_value(field->name, row[i], value.c_str());
      }
      send->decoration("\n");
      break;
   case VERT_LIST:
      Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields);
      sql_field_seek(mdb, 0);
      for (i = 0; i < num_fields; i++) {
         field = sql_fetch_field(mdb);
         if (!field) {
            break;
         }
         if (row[i] == NULL) {
            key.bsprintf(" %*s: ", max_len, field->name);
            value.bsprintf("%s\n", "NULL");
         } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) {
            key.bsprintf(" %*s: ", max_len, field->name);
            value.bsprintf("%s\n", add_commas(row[i], ewc));
         } else {
            key.bsprintf(" %*s: ", max_len, field->name);
            value.bsprintf("%s\n", row[i]);
         }

         /*
          * Use value format string to send preformated value.
          */
         send->object_key_value(field->name, key.c_str(), row[i], value.c_str());
      }
      send->decoration("\n");
      break;
   default:
      break;
   }
   send->object_end("row");
   return 0;
}
Esempio n. 15
0
int list_result(void *vctx, int nb_col, char **row)
{
   SQL_FIELD *field;
   int i, col_len, max_len = 0;
   int num_fields;
   char buf[2000], ewc[30];

   LIST_CTX *pctx = (LIST_CTX *)vctx;
   DB_LIST_HANDLER *send = pctx->send;
   e_list_type type = pctx->type;
   B_DB *mdb = pctx->mdb;
   void *ctx = pctx->ctx;
   JCR *jcr = pctx->jcr;

   num_fields = sql_num_fields(mdb);
   switch (type) {
   case NF_LIST:
   case RAW_LIST:
      /*
       * No need to calculate things like maximum field lenght for
       * unformated or raw output.
       */
      break;
   case HORZ_LIST:
   case VERT_LIST:
      if (!pctx->once) {
         pctx->once = true;

         Dmsg1(800, "list_result starts looking at %d fields\n", num_fields);
         /*
          * Determine column display widths
          */
         sql_field_seek(mdb, 0);
         for (i = 0; i < num_fields; i++) {
            Dmsg1(800, "list_result processing field %d\n", i);
            field = sql_fetch_field(mdb);
            if (!field) {
               break;
            }
            col_len = cstrlen(field->name);
            if (type == VERT_LIST) {
               if (col_len > max_len) {
                  max_len = col_len;
               }
            } else {
               if (sql_field_is_numeric(mdb, field->type) && (int)field->max_length > 0) { /* fixup for commas */
                  field->max_length += (field->max_length - 1) / 3;
               }
               if (col_len < (int)field->max_length) {
                  col_len = field->max_length;
               }
               if (col_len < 4 && !sql_field_is_not_null(mdb, field->flags)) {
                  col_len = 4;                 /* 4 = length of the word "NULL" */
               }
               field->max_length = col_len;    /* reset column info */
            }
         }

         pctx->num_rows++;

         Dmsg0(800, "list_result finished first loop\n");
         if (type == VERT_LIST) {
            break;
         }

         Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields);

         /*
          * Keep the result to display the same line at the end of the table
          */
         list_dashes(mdb, last_line_handler, pctx);
         send(ctx, pctx->line);

         send(ctx, "|");
         sql_field_seek(mdb, 0);
         for (i = 0; i < num_fields; i++) {
            Dmsg1(800, "list_result looking at field %d\n", i);
            field = sql_fetch_field(mdb);
            if (!field) {
               break;
            }
            max_len = max_length(field->max_length);
            bsnprintf(buf, sizeof(buf), " %-*s |", max_len, field->name);
            send(ctx, buf);
         }
         send(ctx, "\n");
         list_dashes(mdb, send, ctx);
      }
      break;
   default:
      break;
   }

   switch (type) {
   case NF_LIST:
   case RAW_LIST:
      Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields);
      sql_field_seek(mdb, 0);
      for (i = 0; i < num_fields; i++) {
         field = sql_fetch_field(mdb);
         if (!field) {
            break;
         }
         if (row[i] == NULL) {
            bsnprintf(buf, sizeof(buf), " %s", "NULL");
         } else {
            bsnprintf(buf, sizeof(buf), " %s", row[i]);
         }
         send(ctx, buf);
      }
      if (type != RAW_LIST) {
         send(ctx, "\n");
      }
      break;
   case HORZ_LIST:
      Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields);
      sql_field_seek(mdb, 0);
      send(ctx, "|");
      for (i = 0; i < num_fields; i++) {
         field = sql_fetch_field(mdb);
         if (!field) {
            break;
         }
         max_len = max_length(field->max_length);
         if (row[i] == NULL) {
            bsnprintf(buf, sizeof(buf), " %-*s |", max_len, "NULL");
         } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) {
            bsnprintf(buf, sizeof(buf), " %*s |", max_len,
                      add_commas(row[i], ewc));
         } else {
            bsnprintf(buf, sizeof(buf), " %-*s |", max_len, row[i]);
         }
         send(ctx, buf);
      }
      send(ctx, "\n");
      break;
   case VERT_LIST:
      Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields);
      sql_field_seek(mdb, 0);
      for (i = 0; i < num_fields; i++) {
         field = sql_fetch_field(mdb);
         if (!field) {
            break;
         }
         if (row[i] == NULL) {
            bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL");
         } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) {
            bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name,
                      add_commas(row[i], ewc));
         } else {
            bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]);
         }
         send(ctx, buf);
      }
      send(ctx, "\n");
      break;
   default:
      break;
   }
   return 0;
}
Esempio n. 16
0
/*************************************************************************
 *
 *	Function: sql_select_query
 *
 *	Purpose: Issue a select query to the database
 *
 *************************************************************************/
static int sql_select_query(SQLSOCK *sqlsocket, SQL_CONFIG *config, char *querystr) {

	int		x;
	int		y;
	int		colcount;
	OCIParam	*param;
	OCIDefine	*define;
	ub2		dtype;
	ub2		dsize;
	char		**rowdata=NULL;
	sb2		*indicators;
	rlm_sql_oracle_sock *oracle_sock = sqlsocket->conn;

	if (config->sqltrace)
		DEBUG(querystr);
	if (oracle_sock->conn == NULL) {
		radlog(L_ERR, "rlm_sql_oracle: Socket not connected");
		return SQL_DOWN;
	}

	if (OCIStmtPrepare (oracle_sock->queryHandle, oracle_sock->errHandle,
				querystr, strlen(querystr),
				OCI_NTV_SYNTAX, OCI_DEFAULT))  {
		radlog(L_ERR,"rlm_sql_oracle: prepare failed in sql_select_query: %s",sql_error(sqlsocket, config));
		return -1;
	}

	/* Query only one row by default (for now) */
	x = OCIStmtExecute(oracle_sock->conn,
				oracle_sock->queryHandle,
				oracle_sock->errHandle,
				(ub4) 0,
				(ub4) 0,
				(OCISnapshot *) NULL,
				(OCISnapshot *) NULL,
				(ub4) OCI_DEFAULT);

	if (x == OCI_NO_DATA) {
		/* Nothing to fetch */
		return 0;
	}

	if (x != OCI_SUCCESS) {
		radlog(L_ERR,"rlm_sql_oracle: query failed in sql_select_query: %s",
				sql_error(sqlsocket, config));
		return sql_check_error(sqlsocket, config);
	}

	/*
	 * Define where the output from fetch calls will go
	 *
	 * This is a gross hack, but it works - we convert
	 * all data to strings for ease of use.  Fortunately, most
	 * of the data we deal with is already in string format.
	 */
	colcount = sql_num_fields(sqlsocket, config);

	/* DEBUG2("sql_select_query(): colcount=%d",colcount); */

	/*
	 *	FIXME: These malloc's can probably go, as the schema
	 *	is fixed...
	 */
	rowdata=(char **)rad_malloc(sizeof(char *) * (colcount+1) );
	memset(rowdata, 0, (sizeof(char *) * (colcount+1) ));
	indicators = (sb2 *) rad_malloc(sizeof(sb2) * (colcount+1) );
	memset(indicators, 0, sizeof(sb2) * (colcount+1));

	for (y=1; y <= colcount; y++) {
		x=OCIParamGet(oracle_sock->queryHandle, OCI_HTYPE_STMT,
				oracle_sock->errHandle,
				(dvoid **)&param,
				(ub4) y);
		if (x != OCI_SUCCESS) {
			radlog(L_ERR,"rlm_sql_oracle: OCIParamGet() failed in sql_select_query: %s",
				sql_error(sqlsocket, config));
			return -1;
		}

		x=OCIAttrGet((dvoid*)param, OCI_DTYPE_PARAM,
			   (dvoid*)&dtype, (ub4*)0, OCI_ATTR_DATA_TYPE,
			   oracle_sock->errHandle);
		if (x != OCI_SUCCESS) {
			radlog(L_ERR,"rlm_sql_oracle: OCIAttrGet() failed in sql_select_query: %s",
				sql_error(sqlsocket, config));
			return -1;
		}

		dsize=MAX_DATASTR_LEN;

		/*
		 * Use the retrieved length of dname to allocate an output
		 * buffer, and then define the output variable (but only
		 * for char/string type columns).
		 */
		switch(dtype) {
#ifdef SQLT_AFC
		case SQLT_AFC:	/* ansii fixed char */
#endif
#ifdef SQLT_AFV
		case SQLT_AFV:	/* ansii var char */
#endif
		case SQLT_VCS:	/* var char */
		case SQLT_CHR:	/* char */
		case SQLT_STR:	/* string */
			x=OCIAttrGet((dvoid*)param, (ub4) OCI_DTYPE_PARAM,
				   (dvoid*) &dsize, (ub4 *)0, (ub4) OCI_ATTR_DATA_SIZE,
				   oracle_sock->errHandle);
			if (x != OCI_SUCCESS) {
				radlog(L_ERR,"rlm_sql_oracle: OCIAttrGet() failed in sql_select_query: %s",
					sql_error(sqlsocket, config));
				return -1;
			}
			rowdata[y-1]=rad_malloc(dsize+1);
			memset(rowdata[y-1], 0, dsize+1);
			break;
		case SQLT_DAT:
		case SQLT_INT:
		case SQLT_UIN:
		case SQLT_FLT:
		case SQLT_PDN:
		case SQLT_BIN:
		case SQLT_NUM:
			rowdata[y-1]=rad_malloc(dsize+1);
			memset(rowdata[y-1], 0, dsize+1);
			break;
		default:
			dsize=0;
			rowdata[y-1]=NULL;
			break;
		}

		indicators[y-1] = 0;
		x=OCIDefineByPos(oracle_sock->queryHandle,
				&define,
				oracle_sock->errHandle,
				y,
				(ub1 *) rowdata[y-1],
				dsize+1,
				SQLT_STR,
				&indicators[y-1],
				(dvoid *) 0,
				(dvoid *) 0,
				OCI_DEFAULT);

		/*
		 *	FIXME: memory leaks of indicators & rowdata?
		 */
		if (x != OCI_SUCCESS) {
			radlog(L_ERR,"rlm_sql_oracle: OCIDefineByPos() failed in sql_select_query: %s",
				sql_error(sqlsocket, config));
			return -1;
		}
	}

	oracle_sock->results=rowdata;
	oracle_sock->indicators=indicators;

	return 0;
}
Esempio n. 17
0
/*
 * If full_list is set, we list vertically, otherwise, we
 *  list on one line horizontally.
 * Return number of rows
 */
int list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type)
{
   SQL_FIELD *field;
   SQL_ROW row;
   int i, col_len, max_len = 0;
   int num_fields;
   char buf[2000], ewc[30];

   Dmsg0(800, "list_result starts\n");
   if (sql_num_rows(mdb) == 0) {
      send(ctx, _("No results to list.\n"));
      return sql_num_rows(mdb);
   }

   num_fields = sql_num_fields(mdb);
   switch (type) {
   case NF_LIST:
   case RAW_LIST:
      /*
       * No need to calculate things like column widths for
       * unformated or raw output.
       */
      break;
   case HORZ_LIST:
   case VERT_LIST:
      Dmsg1(800, "list_result starts looking at %d fields\n", num_fields);
      /*
       * Determine column display widths
       */
      sql_field_seek(mdb, 0);
      for (i = 0; i < num_fields; i++) {
         Dmsg1(800, "list_result processing field %d\n", i);
         field = sql_fetch_field(mdb);
         if (!field) {
            break;
         }
         col_len = cstrlen(field->name);
         if (type == VERT_LIST) {
            if (col_len > max_len) {
               max_len = col_len;
            }
         } else {
            if (sql_field_is_numeric(mdb, field->type) && (int)field->max_length > 0) { /* fixup for commas */
               field->max_length += (field->max_length - 1) / 3;
            }
            if (col_len < (int)field->max_length) {
               col_len = field->max_length;
            }
            if (col_len < 4 && !sql_field_is_not_null(mdb, field->flags)) {
               col_len = 4;                 /* 4 = length of the word "NULL" */
            }
            field->max_length = col_len;    /* reset column info */
         }
      }
      break;
   }

   Dmsg0(800, "list_result finished first loop\n");

   switch (type) {
   case NF_LIST:
   case RAW_LIST:
      Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields);
      while ((row = sql_fetch_row(mdb)) != NULL) {
         sql_field_seek(mdb, 0);
         for (i = 0; i < num_fields; i++) {
            field = sql_fetch_field(mdb);
            if (!field) {
               break;
            }
            if (row[i] == NULL) {
               bsnprintf(buf, sizeof(buf), " %s", "NULL");
            } else {
               bsnprintf(buf, sizeof(buf), " %s", row[i]);
            }
            send(ctx, buf);
         }
         if (type != RAW_LIST) {
            send(ctx, "\n");
         }
      }
      break;
   case HORZ_LIST:
      Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields);
      list_dashes(mdb, send, ctx);
      send(ctx, "|");
      sql_field_seek(mdb, 0);
      for (i = 0; i < num_fields; i++) {
         Dmsg1(800, "list_result looking at field %d\n", i);
         field = sql_fetch_field(mdb);
         if (!field) {
            break;
         }
         max_len = max_length(field->max_length);
         bsnprintf(buf, sizeof(buf), " %-*s |", max_len, field->name);
         send(ctx, buf);
      }
      send(ctx, "\n");
      list_dashes(mdb, send, ctx);

      Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields);
      while ((row = sql_fetch_row(mdb)) != NULL) {
         sql_field_seek(mdb, 0);
         send(ctx, "|");
         for (i = 0; i < num_fields; i++) {
            field = sql_fetch_field(mdb);
            if (!field) {
               break;
            }
            max_len = max_length(field->max_length);
            if (row[i] == NULL) {
               bsnprintf(buf, sizeof(buf), " %-*s |", max_len, "NULL");
            } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) {
               bsnprintf(buf, sizeof(buf), " %*s |", max_len,
                         add_commas(row[i], ewc));
            } else {
               bsnprintf(buf, sizeof(buf), " %-*s |", max_len, row[i]);
            }
            send(ctx, buf);
         }
         send(ctx, "\n");
      }
      list_dashes(mdb, send, ctx);
      break;
   case VERT_LIST:
      Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields);
      while ((row = sql_fetch_row(mdb)) != NULL) {
         sql_field_seek(mdb, 0);
         for (i = 0; i < num_fields; i++) {
            field = sql_fetch_field(mdb);
            if (!field) {
               break;
            }
            if (row[i] == NULL) {
               bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL");
            } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) {
               bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name,
                   add_commas(row[i], ewc));
            } else {
               bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]);
            }
            send(ctx, buf);
         }
         send(ctx, "\n");
      }
      break;
   }
   return sql_num_rows(mdb);
}
Esempio n. 18
0
/*************************************************************************
 *
 *	Function: sql_fetch_row
 *
 *	Purpose: database specific fetch_row. Returns a SQL_ROW struct
 *               with all the data for the query in 'sqlsocket->row'. Returns
 *		 0 on success, -1 on failure, SQL_DOWN if database is down.
 *
 *************************************************************************/
static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config)
{
	int returnCode = -1;
	rlm_sql_sqlite_sock *sqlite_sock = sqlsocket->conn;
	const char *blob;
	int blobLen;
	int status;
	int colindex = 0;
	int colcount = 0;
	int coltype = 0;
	int colintvalue = 0;
	int ret_blob_size = 0;
	char **rowdata = NULL;
	const unsigned char *textStr;
	char intStr[256];
	
	status = sqlite3_step(sqlite_sock->pStmt);
	radlog(L_DBG, "rlm_sql_sqlite: sqlite3_step = %d\n", status);
	if (status == SQLITE_DONE) {
		sql_free_rowdata(sqlsocket, sqlite_sock->columnCount);
		return 0;
	}
	else if (status == SQLITE_ROW) {
		if (sqlite_sock->columnCount == 0) {
			sqlite_sock->columnCount = sql_num_fields(sqlsocket, config);
		}
		colcount = sqlite_sock->columnCount;
		if (colcount == 0)
			return -1;
		
		sql_free_rowdata(sqlsocket, colcount);
		
		ret_blob_size = sizeof(char *) * (colcount+1);
		rowdata = (char **)rad_malloc(ret_blob_size);		/* Space for pointers */
		if (rowdata != NULL) {
			memset(rowdata, 0, ret_blob_size);				/* NULL-pad the pointers */
			sqlsocket->row = rowdata;
		}
		
		for (colindex = 0; colindex < colcount; colindex++)
		{
			coltype = sqlite3_column_type(sqlite_sock->pStmt, colindex);
			switch (coltype)
			{
				case SQLITE_INTEGER:
					colintvalue = sqlite3_column_int(sqlite_sock->pStmt, colindex);
					snprintf(intStr, sizeof(intStr), "%d", colintvalue);
					rowdata[colindex] = strdup(intStr);
					break;
					
				case SQLITE_TEXT:
					textStr = sqlite3_column_text(sqlite_sock->pStmt, colindex);
					if (textStr != NULL)
						rowdata[colindex] = strdup((const char *)textStr);
					break;
					
				case SQLITE_BLOB:
					blob = sqlite3_column_blob(sqlite_sock->pStmt, colindex);
					if (blob != NULL) {
						blobLen = sqlite3_column_bytes(sqlite_sock->pStmt, colindex);
						rowdata[colindex] = (char *)rad_malloc(blobLen + 1);
						if (rowdata[colindex] != NULL) {
							memcpy(rowdata[colindex], blob, blobLen);
						}
					}
					break;
					
				default:
					break;
			}
		}
		
		returnCode = 0;
	}
	
	return returnCode;
}