Skip to content

Commit

Permalink
regex filters, various cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
nmandery committed May 25, 2012
1 parent 836dd50 commit e11e7d8
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 46 deletions.
3 changes: 2 additions & 1 deletion src/chunk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ Line::Line(std::string _contents, linenumber_t _number)
// ### Chunk ############################################

Chunk::Chunk()
: sql_lines(), start_comment(""), end_comment(""), start_line(0), end_line(0)
: sql_lines(), start_comment(""), end_comment(""),
start_line(0), end_line(0), diagnostics()
{
}

Expand Down
2 changes: 1 addition & 1 deletion src/chunk.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace PsqlChunks
std::string msg_detail;
std::string msg_hint;

Diagnostics() : error_line(1), status(Ok), sqlstate(""),
Diagnostics() : runtime(), error_line(1), status(Ok), sqlstate(""),
msg_primary(""), msg_detail(""), msg_hint("")
{
runtime.tv_sec = 0;
Expand Down
39 changes: 38 additions & 1 deletion src/filter.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <sstream>
#include <cstdlib>

#include "filter.h"
#include "debug.h"
Expand Down Expand Up @@ -83,15 +84,51 @@ LineFilter::match(const Chunk& chunk)
bool
RegexFilter::matchString(std::string &str)
{
return true; // TODO
if (re) {
return (regexec(re, str.c_str(), 0, NULL, 0) == 0);
}

return false;
}

bool
RegexFilter::setParams(const char * params, std::string &errmsg)
{
if (!re) {
re = new regex_t;
}
else {
regfree(re);
}
int errcode = regcomp(re, params, REG_EXTENDED | REG_ICASE);
if (errcode != 0) {
size_t len = regerror(errcode, re, NULL, 0);
char * buff = new char[len];
if(buff) {
regerror(errcode, re, buff, len);
errmsg = buff;
delete[] buff;
}
else {
errmsg = "Invalid regex";
}
regfree(re);
delete re;
re = NULL;

return false;
}
return true;
}

RegexFilter::~RegexFilter()
{
if (re) {
regfree(re);
delete re;
}
}

bool
DescriptionRegexFilter::match(const Chunk& chunk)
{
Expand Down
17 changes: 15 additions & 2 deletions src/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

#include <vector>
#include <string>

#include <regex.h>

#include "chunk.h"

namespace PsqlChunks
Expand Down Expand Up @@ -44,7 +47,7 @@ namespace PsqlChunks
std::vector<Filter*> filters;

public:
FilterChain() {};
FilterChain() : filters() {};
~FilterChain();

void addFilter(Filter * filter);
Expand All @@ -63,7 +66,7 @@ namespace PsqlChunks
std::vector<linenumber_t> linenumbers;

public:
LineFilter() : Filter() {};
LineFilter() : Filter(), linenumbers() {};
~LineFilter() {};

/**
Expand All @@ -82,10 +85,20 @@ namespace PsqlChunks
*/
class RegexFilter : public Filter
{
private:
regex_t * re;

RegexFilter(const RegexFilter&);
RegexFilter& operator=(const RegexFilter&);

protected:
bool matchString(std::string &str);

public:

RegexFilter() : Filter(), re(NULL) {};
~RegexFilter();

bool setParams(const char * params, std::string &errmsg);
};

Expand Down
102 changes: 63 additions & 39 deletions src/psqlchunks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,35 +62,43 @@ enum CommandRc {


struct Settings {
const char * db_port;
const char * db_user;
const char * db_name;
const char * db_host;
bool ask_pass;
bool commit_sql;
bool abort_after_failed;
Command command;
bool is_terminal;
unsigned int context_lines;
bool print_filenames;
const char * client_encoding;

FilterChain filterchain;

Settings() :
db_port(0),
db_user(0),
db_name(0),
db_host(0),
ask_pass(false),
commit_sql(false),
abort_after_failed(false),
command(LIST),
is_terminal(false),
context_lines(DEFAULT_CONTEXT_LINES),
print_filenames(true),
client_encoding(0)
{};
public:
const char * db_port;
const char * db_user;
const char * db_name;
const char * db_host;
bool ask_pass;
bool commit_sql;
bool abort_after_failed;
Command command;
bool is_terminal;
unsigned int context_lines;
bool print_filenames;
const char * client_encoding;

FilterChain filterchain;

Settings() :
db_port(0),
db_user(0),
db_name(0),
db_host(0),
ask_pass(false),
commit_sql(false),
abort_after_failed(false),
command(LIST),
is_terminal(false),
context_lines(DEFAULT_CONTEXT_LINES),
print_filenames(true),
client_encoding(0),
filterchain()
{};

private:
Settings(const Settings&);
Settings& operator=(const Settings&);


};

// allow signal handler to access db
Expand Down Expand Up @@ -201,6 +209,9 @@ print_help()
" -L [lines] use only chunks which span the give lines.\n"
" lines is a commaseperated list of line numbers. Example:\n"
" 1,78,345\n"
" -I [regex] description comments have to match this regular expression\n"
" (POSIX extended regular expression), case insensitive\n"
" -S [regex] SQL has to match this POSIX extended regular expression. case insensitive\n"
"\n"
"SQL Handling:\n"
" -C commit SQL to the database. Default is performing a rollback\n"
Expand Down Expand Up @@ -310,7 +321,7 @@ cmd_run_print_diagnostics(Settings & settings, Chunk & chunk) {
if (settings.context_lines < (chunk.end_line - chunk.diagnostics.error_line)) {
out_end = chunk.diagnostics.error_line + settings.context_lines;
}
log_debug("out_start: %u, out_end: %u", out_start, out_end);
log_debug("out_start: %lu, out_end: %lu", out_start, out_end);

// output sql
linevector_t sql_lines = chunk.getSqlLines();
Expand Down Expand Up @@ -515,6 +526,20 @@ handle_files(Settings &settings, char * files[], int nufiles)
}


template <class T>
void
add_filter(FilterChain &filterchain, const char * params)
{
T * filter = new T();
std::string errmsg;
if (!filter->setParams(params, errmsg)) {
delete filter;
quit(errmsg.c_str());
}
filterchain.addFilter(filter);
}


int
main(int argc, char * argv[] )
{
Expand All @@ -540,7 +565,7 @@ main(int argc, char * argv[] )

// read options
char opt;
while ( (opt = getopt(argc, argv, "l:p:U:d:h:WCaFE:L:")) != -1) {
while ( (opt = getopt(argc, argv, "l:p:U:d:h:WCaFE:L:S:I:")) != -1) {
switch (opt) {
case 'p': /* port */
settings.db_port = optarg;
Expand Down Expand Up @@ -587,14 +612,13 @@ main(int argc, char * argv[] )
settings.client_encoding = optarg;
break;
case 'L': /* line filter */
{
LineFilter * linefilter = new LineFilter();
std::string errmsg;
if (!linefilter->setParams(optarg, errmsg)) {
quit(errmsg.c_str());
}
settings.filterchain.addFilter(linefilter);
}
add_filter<LineFilter>(settings.filterchain, optarg);
break;
case 'I': /* description regex filter */
add_filter<DescriptionRegexFilter>(settings.filterchain, optarg);
break;
case 'S': /* sql regex filter */
add_filter<ContentRegexFilter>(settings.filterchain, optarg);
break;
default:
quit("Unknown option.");
Expand Down
7 changes: 5 additions & 2 deletions src/scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ namespace PsqlChunks
ChunkScanner * scanner;
Chunk chunk;

ChunkIterator(const ChunkIterator&);
ChunkIterator& operator=(const ChunkIterator&);

inline void fetchChunk()
{
if (scanner && !scanner->nextChunk(chunk)) {
Expand All @@ -85,13 +88,13 @@ namespace PsqlChunks
}

public:
ChunkIterator(std::istream& is) : scanner(NULL)
ChunkIterator(std::istream& is) : scanner(NULL), chunk()
{
scanner = new ChunkScanner(is);
fetchChunk();
};

ChunkIterator() : scanner(NULL) {};
ChunkIterator() : scanner(NULL), chunk() {};

~ChunkIterator() { delete scanner; };

Expand Down

0 comments on commit e11e7d8

Please sign in to comment.