Monthly Archives: March 2015

PostgreSQL’s ~/.pgpass Parser in Common Lisp

Here is a quick and dirty PostgreSQL ~/.pgpass parser, in Common Lisp.

It depends on Split Sequence, conveniently loaded with QuickLisp, like so.

(ql:quickload :split-sequence :silent t)

And here is the actual code. It’s not wrapped in a function, and the other connection parameters are hard coded. This can use some refactoring; particularly with relevance to error handling.

(defvar pguser "user")
(defvar pgdb "database")
(defvar pghost "hostname")
(defvar pgport 5432)

(defvar pgpass
  (handler-case
      (with-open-file 
          (.pgpass "~/.pgpass"
		   :direction :input
		   :if-does-not-exist nil)
	(flet ((wildcard-string= (a b)
		 (or (string= a "*")
		     (string= a (princ-to-string b)))))

	  (loop for line = (read-line .pgpass nil)
	    while line
	    when (destructuring-bind (host port db user passwd)
		   (split-sequence:split-sequence #\: line)
		   (if (and (wildcard-string= host pghost)
			    (wildcard-string= port pgport)
			    (wildcard-string= db pgdb)
			    (wildcard-string= user pguser))
		       passwd))
	    return it)))
    (file-error (e)
		(format *error-output* "Unable to load password file; ~A~%"
			e)
		nil)))

(format t "Password: ~A~%" pgpass)

Licenses

Split-Sequence is part of CL-Utilities and Public Domain.

QuickLisp is licensed under an MIT-style license.

The example code above is © 2015 Johann ‘Myrkraverk’ Oskarsson and licensed under the Two-clause BSD license.

CTemplate Emitter for Stream Output

Google’s CTemplate has very customizable output features, yet it does not come with an emitter (the type of class that actually outputs the template with all the variables filled in) for standard streams.  Hence there is no default way to output to std::cout.

Or I was unable to find one.

Therefore, here is a very simple emitter for stream output.

class StreamEmitter: public ctemplate::ExpandEmitter
{
public:
    StreamEmitter( std::ostream &out ) : sout( out )
    {
    }

    virtual void Emit( char c )
    {
        sout << c;
    }

    virtual void Emit( const std::string &s )
    {
        sout << s;
    }

    virtual void Emit( const char *s )
    {
        sout << s;
    }

    virtual void Emit( const char *s, size_t len )
    {
        sout.write( s, len );
    }

private:
    std::ostream &sout;
};

Then it can be used like this.

// Assume pageDict has been initialized and the variables filled in...

    StreamEmitter coutEmitter( std::cout );

    ctemplate::ExpandTemplate( "template_file", ctemplate::DO_NOT_STRIP, &pageDict, &coutEmitter );

Am I really the only one who wants to emit templates to streams?


Licenese: Three clause BSD (same as CTemplate itself).