From 4f64364842c11d4c5e2d032279bcdb37e8eb9e67 Mon Sep 17 00:00:00 2001
From: Dan Goodliffe <dan@randomdan.homeip.net>
Date: Tue, 26 May 2015 21:01:24 +0100
Subject: Add support in the lexer for accessing the current script's folder

---
 project2/sql/mockDatabase.cpp       |  2 +-
 project2/sql/sql.ll                 |  6 ++++++
 project2/sql/sqlFlexLexer.cpp       | 11 +++++++++--
 project2/sql/sqlFlexLexer.h         |  6 +++++-
 project2/sql/unittests/pqschema.sql |  5 +++++
 project2/sql/unittests/testpq.cpp   | 18 +++++++++++++++++-
 6 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/project2/sql/mockDatabase.cpp b/project2/sql/mockDatabase.cpp
index 47fe99f..b357abd 100644
--- a/project2/sql/mockDatabase.cpp
+++ b/project2/sql/mockDatabase.cpp
@@ -49,7 +49,7 @@ MockDatabase::PlaySchemaScript(DB::Connection * conn, const boost::filesystem::p
 	Logger()->messagebf(LOG_DEBUG, "%s << %s", mockName, s);
 	std::ifstream f;
 	f.open(s.string());
-	auto lexer = boost::shared_ptr<FlexLexer>(new sqlFlexLexer(f, conn));
+	auto lexer = boost::shared_ptr<FlexLexer>(new sqlFlexLexer(s.parent_path(), f, conn));
 	while(lexer->yylex() != 0) ;
 	f.close();
 }
diff --git a/project2/sql/sql.ll b/project2/sql/sql.ll
index 39f9052..604a53d 100644
--- a/project2/sql/sql.ll
+++ b/project2/sql/sql.ll
@@ -24,6 +24,8 @@ dolq_start [A-Za-z\200-\377_]
 dolq_cont [A-Za-z\200-\377_0-9]
 dollarquote \$({dolq_start}{dolq_cont}*)?\$
 
+p2mockscriptdir "$P2MOCKSCRIPTDIR"
+
 %x COMMENT
 %x STATEMENT
 %x QUOTE
@@ -74,6 +76,10 @@ dollarquote \$({dolq_start}{dolq_cont}*)?\$
 	yy_pop_state();
 }
 
+<QUOTE>{p2mockscriptdir} {
+	statement += MockScriptDir();
+}
+
 <QUOTE>{quote_apos} {
 	statement += YYText();
 }
diff --git a/project2/sql/sqlFlexLexer.cpp b/project2/sql/sqlFlexLexer.cpp
index 2b26f20..cbf2416 100644
--- a/project2/sql/sqlFlexLexer.cpp
+++ b/project2/sql/sqlFlexLexer.cpp
@@ -2,9 +2,10 @@
 #include "sqlFlexLexer.h"
 #include <logger.h>
 
-sqlFlexLexer::sqlFlexLexer(std::istream & f, DB::Connection * c) :
+sqlFlexLexer::sqlFlexLexer(const boost::filesystem::path & s, std::istream & f, DB::Connection * c) :
 	yyFlexLexer(&f, NULL),
-	conn(c)
+	conn(c),
+	script(s)
 {
 }
 
@@ -26,3 +27,9 @@ sqlFlexLexer::Statement(const std::string & text)
 	conn->execute(text);
 }
 
+std::string
+sqlFlexLexer::MockScriptDir() const
+{
+	return script.string();
+}
+
diff --git a/project2/sql/sqlFlexLexer.h b/project2/sql/sqlFlexLexer.h
index 09c3eae..fbaf799 100644
--- a/project2/sql/sqlFlexLexer.h
+++ b/project2/sql/sqlFlexLexer.h
@@ -1,18 +1,22 @@
 #include <istream>
+#include <string>
 #include <connection.h>
+#include <boost/filesystem/path.hpp>
 
 class sqlFlexLexer : public yyFlexLexer {
 	public:
-		sqlFlexLexer(std::istream &, DB::Connection *);
+		sqlFlexLexer(const boost::filesystem::path &, std::istream &, DB::Connection *);
 		int yylex();
 
 		void Comment(const std::string &);
 		void Statement(const std::string &);
+		std::string MockScriptDir() const;
 
 	protected:
 		void LexerOutput(const char *, int) override;
 
 	private:
 		DB::Connection * conn;
+		const boost::filesystem::path script;
 };
 
diff --git a/project2/sql/unittests/pqschema.sql b/project2/sql/unittests/pqschema.sql
index 21277ca..b0581ab 100644
--- a/project2/sql/unittests/pqschema.sql
+++ b/project2/sql/unittests/pqschema.sql
@@ -18,6 +18,11 @@ CREATE TABLE test(
 
 INSERT INTO test VALUES(4, 123.45, 'some text with a ; in it and a '' too', true, '2015-04-27 23:06:03', '1 day 14:13:12');
 
+CREATE TABLE test2(
+		path text not null);
+
+INSERT INTO test2 VALUES('$P2MOCKSCRIPTDIR/pqschema.sql');
+
 CREATE FUNCTION event_tsvector() RETURNS int
 LANGUAGE sql STABLE
 AS $tag$
diff --git a/project2/sql/unittests/testpq.cpp b/project2/sql/unittests/testpq.cpp
index 38b07a2..0890bee 100644
--- a/project2/sql/unittests/testpq.cpp
+++ b/project2/sql/unittests/testpq.cpp
@@ -64,7 +64,7 @@ void
 assertColumnValueHelper(DB::SelectCommand & sel, unsigned int col, const T & t)
 {
 	HandleAsVariableType h;
-	sel[col].apply(h); 
+	sel[col].apply(h);
 	BOOST_REQUIRE_EQUAL(t, h.variable.as<T>());
 }
 
@@ -114,5 +114,21 @@ BOOST_AUTO_TEST_CASE( bindAndSelectOther )
 	ds->close();
 }
 
+BOOST_AUTO_TEST_CASE( testP2MockScriptDir )
+{
+	RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("pqmock");
+	auto ro = ds->getReadonly();
+
+	auto select = ro->newSelectCommand("SELECT path FROM test2");
+	select->execute();
+	while (select->fetch()) {
+		HandleAsVariableType h;
+		(*select)[0].apply(h);
+		BOOST_REQUIRE(boost::filesystem::exists(h.variable.as<std::string>()));
+	}
+	delete select;
+	ds->close();
+}
+
 BOOST_AUTO_TEST_SUITE_END();
 
-- 
cgit v1.2.3