<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Artful Code &#187; mysql</title>
	<atom:link href="http://www.artfulcode.net/tags/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.artfulcode.net</link>
	<description>Resources and tips for dynamic, interactive languages.</description>
	<lastBuildDate>Fri, 09 Sep 2011 02:15:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Custom session storage with newLISP Web</title>
		<link>http://www.artfulcode.net/articles/custom-session-storage-with-newlisp-web/</link>
		<comments>http://www.artfulcode.net/articles/custom-session-storage-with-newlisp-web/#comments</comments>
		<pubDate>Fri, 29 May 2009 18:35:52 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[newlisp]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.artfulcode.net/?p=684</guid>
		<description><![CDATA[The Web module's default session storage engine uses serialized contexts in the /tmp directory. The advantage of this method is that, apart from the directory (which is customizable), it is reasonably platform independent and has low overhead. The disadvantages of this are numerous. Files are stored unencrypted, so anyone with access to the server may view them. It is therefor advantageous to design a custom storage module for sessions.]]></description>
			<content:encoded><![CDATA[<p><a href="http://static.artfulcode.net/newlisp/web.lsp.html">The Web module&#8217;s</a> default session storage engine uses serialized contexts in the <em>/tmp</em> directory. The advantage of this method is that, apart from the directory (which is customizable), it is reasonably platform independent and has low overhead. The disadvantages of this are numerous. Files are stored unencrypted, so anyone with access to the server may view them. It is therefor advantageous to design a custom storage module for sessions.<span id="more-684"></span></p>
<p>Storing sessions in a database is a good solution. Backups are easier; persistence and pruning orphaned sessions are simpler. Security is available through the database server&#8217;s security.  We will use MySQL, since it is the best supported in newLISP.</p>
<h2>Setting up the database</h2>
<p>First, we need a table in which to store session data. Using a MySQL <code>TIMESTAMP</code> column will provide us with an automatically updating time stamp on the last modification of the session, which we will use below to find old sessions to remove.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> sessions <span style="color: #66cc66;">&#40;</span>
	sid VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">,</span>
	<span style="color: #993333; font-weight: bold;">DATA</span> TEXT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
	ts TIMESTAMP
<span style="color: #66cc66;">&#41;</span></pre></div></div>

<h2>Designing the storage module</h2>
<p>Several functions need to be defined to handle storing data. First, we must ensure that the <a href="http://www.newlisp.org/code/modules/mysql.lsp.html">MySQL module</a> is loaded and initialized. We will do this in a separate module that we will call <code>DBSessions</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="newlisp" style="font-family:monospace;"><span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">context</span> 'DBSessions<span style="color: #AF0500;">&#41;</span>
&nbsp;
<span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">unless</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">sym</span> <span style="color: #3AA43E;">&quot;MYSQL&quot;</span> 'MySQL <span style="color: #2028B8;">nil</span><span style="color: #AF0500;">&#41;</span> <span style="color: #808080; font-style: italic;">; do not reinitialize if already loaded</span>
  <span style="color: #AF0500;">&#40;</span>module <span style="color: #3AA43E;">&quot;mysql5.lsp&quot;</span><span style="color: #AF0500;">&#41;</span> <span style="color: #808080; font-style: italic;">; with newlisp 10.1, this will change to &quot;mysql.lsp&quot;</span>
  <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">init</span><span style="color: #AF0500;">&#41;</span>
  <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">connect</span> <span style="color: #3AA43E;">&quot;127.0.0.1&quot;</span> <span style="color: #3AA43E;">&quot;user&quot;</span> <span style="color: #3AA43E;">&quot;secret&quot;</span> <span style="color: #3AA43E;">&quot;somedb&quot;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
&nbsp;
<span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">context</span> '<span style="color: #2028B8;">MAIN</span><span style="color: #AF0500;">&#41;</span></pre></div></div>

<p>Next, we define a function to create or resume a session from the database. Sessions are stored in memory as contexts, making our job easier. Our function will query MySQL to see if the session id exists, and either create a new session and insert it or retrieve an existing session and load it. The function <code>Web:session-id</code> gives us the current session id from the session cookie or creates a new one and sends the client a cookie to store it. <code>Web:session-context</code> returns a symbol pointed to the context storing the current session.</p>

<div class="wp_syntax"><div class="code"><pre class="newlisp" style="font-family:monospace;"><span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">define</span> <span style="color: #AF0500;">&#40;</span>open-session<span style="color: #AF0500;">&#41;</span>
  <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">when</span> <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">query</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">format</span> <span style="color: #3AA43E;">&quot;SELECT data FROM sessions WHERE sid = '%s'&quot;</span> <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-id</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
    <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">let</span> <span style="color: #AF0500;">&#40;</span><span style="color: #AF0500;">&#40;</span>data <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">fetch-row</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
      <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">if</span> data
        <span style="color: #808080; font-style: italic;">;; Evaluate the serialized context into the current session context</span>
        <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">eval-string</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">first</span> data<span style="color: #AF0500;">&#41;</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-</span><span style="color: #2028B8;">context</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
        <span style="color: #808080; font-style: italic;">;; Create a new session and save it</span>
        <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">query</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">format</span> <span style="color: #3AA43E;">&quot;INSERT INTO sessions (sid, data) VALUES ('%s', '%s')&quot;</span>
          <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-id</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
          <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">source</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-</span><span style="color: #2028B8;">context</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span></pre></div></div>

<p>Next, we need a function to write any changes to the session to storage. Since the session is stored as a context, this is quite simple.</p>

<div class="wp_syntax"><div class="code"><pre class="newlisp" style="font-family:monospace;"><span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">define</span> <span style="color: #AF0500;">&#40;</span>close-session<span style="color: #AF0500;">&#41;</span>
  <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">query</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">format</span> <span style="color: #3AA43E;">&quot;UPDATE sessions SET data = '%s' WHERE sid = '%s'&quot;</span>
    <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">source</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-</span><span style="color: #2028B8;">context</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
    <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-id</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span></pre></div></div>

<p>We also need a function to delete entire sessions when necessary. This is also simple.</p>

<div class="wp_syntax"><div class="code"><pre class="newlisp" style="font-family:monospace;"><span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">define</span> <span style="color: #AF0500;">&#40;</span>delete-session<span style="color: #AF0500;">&#41;</span>
  <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">query</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">format</span> <span style="color: #3AA43E;">&quot;DELETE FROM sessions WHERE sid = '%s'&quot;</span>
    <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-id</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span></pre></div></div>

<p>Finally, a function to cull old sessions from the database. For this, we use the variable <code>Web:SESSION_MAX_AGE</code> to determine which sessions have expired.</p>

<div class="wp_syntax"><div class="code"><pre class="newlisp" style="font-family:monospace;"><span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">define</span> <span style="color: #AF0500;">&#40;</span>clean-sessions<span style="color: #AF0500;">&#41;</span>
  <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">query</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">format</span> <span style="color: #3AA43E;">&quot;DELETE FROM sessions WHERE NOW() &gt;= DATE_ADD(ts, INTERVAL %d SECOND)&quot;</span>
    Web:<span style="color: #2028B8;">SESSION_MAX_AGE</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span></pre></div></div>

<h2>Registering the handler in Web</h2>
<p>Last, the handler functions need to be registered in the <code>Web</code> module.</p>

<div class="wp_syntax"><div class="code"><pre class="newlisp" style="font-family:monospace;"><span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">define-session-handlers</span>
  open-session close-session delete-session clean-sessions<span style="color: #AF0500;">&#41;</span></pre></div></div>

<h2>Putting it all together</h2>

<div class="wp_syntax"><div class="code"><pre class="newlisp" style="font-family:monospace;"><span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">unless</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">sym</span> <span style="color: #3AA43E;">&quot;MYSQL&quot;</span> 'MySQL <span style="color: #2028B8;">nil</span><span style="color: #AF0500;">&#41;</span> <span style="color: #808080; font-style: italic;">; do not reinitialize if already loaded</span>
  <span style="color: #AF0500;">&#40;</span>module <span style="color: #3AA43E;">&quot;mysql5.lsp&quot;</span><span style="color: #AF0500;">&#41;</span> <span style="color: #808080; font-style: italic;">; with newlisp 10.1, this will change to &quot;mysql.lsp&quot;</span>
  <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">init</span><span style="color: #AF0500;">&#41;</span>
  <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">connect</span> <span style="color: #3AA43E;">&quot;127.0.0.1&quot;</span> <span style="color: #3AA43E;">&quot;user&quot;</span> <span style="color: #3AA43E;">&quot;secret&quot;</span> <span style="color: #3AA43E;">&quot;somedb&quot;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
&nbsp;
<span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">context</span> 'DBSessions<span style="color: #AF0500;">&#41;</span>
&nbsp;
<span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">define</span> <span style="color: #AF0500;">&#40;</span>open-session<span style="color: #AF0500;">&#41;</span>
  <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">when</span> <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">query</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">format</span> <span style="color: #3AA43E;">&quot;SELECT data FROM sessions WHERE sid = '%s'&quot;</span> <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-id</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
    <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">let</span> <span style="color: #AF0500;">&#40;</span><span style="color: #AF0500;">&#40;</span>data <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">fetch-row</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
      <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">if</span> data
        <span style="color: #808080; font-style: italic;">;; Evaluate the serialized context into the current session context</span>
        <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">eval-string</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">first</span> data<span style="color: #AF0500;">&#41;</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-</span><span style="color: #2028B8;">context</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
        <span style="color: #808080; font-style: italic;">;; Create a new session and save it</span>
        <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">query</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">format</span> <span style="color: #3AA43E;">&quot;INSERT INTO sessions (sid, data) VALUES ('%s', '%s')&quot;</span>
          <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-id</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
          <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">source</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-</span><span style="color: #2028B8;">context</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
&nbsp;
<span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">define</span> <span style="color: #AF0500;">&#40;</span>close-session<span style="color: #AF0500;">&#41;</span>
  <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">query</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">format</span> <span style="color: #3AA43E;">&quot;UPDATE sessions SET data = '%s' WHERE sid = '%s'&quot;</span>
    <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">source</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-</span><span style="color: #2028B8;">context</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
    <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-id</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
&nbsp;
<span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">define</span> <span style="color: #AF0500;">&#40;</span>delete-session<span style="color: #AF0500;">&#41;</span>
  <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">query</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">format</span> <span style="color: #3AA43E;">&quot;DELETE FROM sessions WHERE sid = '%s'&quot;</span>
    <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">escape</span> <span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">session-id</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
&nbsp;
<span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">define</span> <span style="color: #AF0500;">&#40;</span>clean-sessions<span style="color: #AF0500;">&#41;</span>
  <span style="color: #AF0500;">&#40;</span>MySQL:<span style="color: #2028B8;">query</span> <span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">format</span> <span style="color: #3AA43E;">&quot;DELETE FROM sessions WHERE NOW() &gt;= DATE_ADD(ts, INTERVAL %d SECOND)&quot;</span>
    Web:<span style="color: #2028B8;">SESSION_MAX_AGE</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span><span style="color: #AF0500;">&#41;</span>
&nbsp;
<span style="color: #AF0500;">&#40;</span>Web:<span style="color: #2028B8;">define-session-handlers</span>
  open-session close-session delete-session clean-sessions<span style="color: #AF0500;">&#41;</span>
&nbsp;
<span style="color: #AF0500;">&#40;</span><span style="color: #2028B8;">context</span> '<span style="color: #2028B8;">MAIN</span><span style="color: #AF0500;">&#41;</span></pre></div></div>

<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Submit article</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fcustom-session-storage-with-newlisp-web%2F&amp;title=Custom+session+storage+with+newLISP+Web" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fcustom-session-storage-with-newlisp-web%2F&amp;title=Custom+session+storage+with+newLISP+Web" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.dzone.com/links/add.html?description=Custom+session+storage+with+newLISP+Web&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fcustom-session-storage-with-newlisp-web%2F&amp;title=Custom+session+storage+with+newLISP+Web" rel="nofollow" title="Add to&nbsp;DZone"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/dzone.png" title="Add to&nbsp;DZone" alt="Add to&nbsp;DZone" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fcustom-session-storage-with-newlisp-web%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fcustom-session-storage-with-newlisp-web%2F&amp;title=Custom+session+storage+with+newLISP+Web" rel="nofollow" title="Add to&nbsp;reddit"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/reddit.png" title="Add to&nbsp;reddit" alt="Add to&nbsp;reddit" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fcustom-session-storage-with-newlisp-web%2F&amp;title=Custom+session+storage+with+newLISP+Web" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fcustom-session-storage-with-newlisp-web%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Custom+session+storage+with+newLISP+Web+@+http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fcustom-session-storage-with-newlisp-web%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.artfulcode.net/articles/custom-session-storage-with-newlisp-web/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A better MySQL module for newLISP</title>
		<link>http://www.artfulcode.net/articles/a-better-mysql-module-for-newlisp/</link>
		<comments>http://www.artfulcode.net/articles/a-better-mysql-module-for-newlisp/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 17:23:32 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[foop]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[newlisp]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.artfulcode.net/?p=491</guid>
		<description><![CDATA[The Mysql module has been written from scratch utilizing some of the more recent features of newLisp, such as FOOP and reference returns. One of its major design goals was to simplify use as well as broaden the features of the standard MySQL module, while at the same time allowing the creation of new, anonymous [...]]]></description>
			<content:encoded><![CDATA[<p>The <strong><code>Mysql</code></strong> module has been written from scratch utilizing some of the more recent features of newLisp, such as FOOP and reference returns. One of its major design goals was to simplify use as well as broaden the features of the standard <a href="http://www.newlisp.org/code/modules/mysql.lsp.html">MySQL module</a>, while at the same time allowing the creation of new, anonymous instances at run-time.<span id="more-491"></span></p>
<p>The <code>Mysql</code> module differs from the distribution standard module in several important ways. Most obviously, it uses <a href="http://www.artfulcode.net/articles/using-the-newlisp-ffi/">FOOP wrappers for MySQL types</a>. It also requires clients to free results instances; in the standard module, only the base MYSQL instance itself must be freed (using <code>MySQL:close-db</code>).</p>
<p>The significance of this is that it is much simpler to create multiple connections (without having to duplicate the entire context at compile time). Result sets are completely independent of each other, and several may be maintained in any state at once. This also means that a spawned process may be given its own Mysql instance to use without having to worry about other processes&#8217; instances interfering. Using the standard module, the entire context would need to be cloned at compile time and given a static symbol reference (e.g., <code>(new 'MySQL 'db)</code>) in order to run multiple instances or connections to a server.</p>
<p>Moreover, because this module uses <code>unpack</code> and MySQL C API accessor functions, there is no need for the client to calculate member offsets in MySQL compound types. So long as newLisp was compiled for the same target as the <code>libmysqlclient</code> library (both are 32 bit or both are 64 bit), everything should work out of the box. Additionally, MySQL errors are now checked in the connect and query functions and re-thrown as interpreter errors. Instead of checking for <code>nil</code> returns and a using MySQL:error to get the error message, standard error  handling with the <code>catch</code> function may be used.</p>
<p>Several convenience functions and macros have been defined in the <code>mysql</code> context for common operations, including connecting to the database and iterating over results without having to worry about catching errors and managing memory. SQL statements may be passed as strings or a list containing a format string and its parameters, which will type-checked and automatically be escaped as needed.</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>mysql<span style="color: #66cc66;">:</span><span style="color: #555;">on-connect</span> '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;localhost&quot;</span> <span style="color: #ff0000;">&quot;user&quot;</span> <span style="color: #ff0000;">&quot;secret&quot;</span> <span style="color: #ff0000;">&quot;my_database&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>db err<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> err
      <span style="color: #66cc66;">&#40;</span>println <span style="color: #ff0000;">&quot;Error! &quot;</span> err<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span>mysql<span style="color: #66cc66;">:</span><span style="color: #555;">row-iter</span> db <span style="color: #ff0000;">&quot;SELECT * FROM some_table&quot;</span> true
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>row<span style="color: #66cc66;">&#41;</span>
          <span style="color: #66cc66;">&#40;</span>println row<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>This module has been tested with MySQL version 5 and 5.1 and newLisp version 10.0.1. It requires newLisp 10.0 or later. You can <a href="http://static.artfulcode.net/newlisp/mysql.lsp.html">download it</a> from the <a href="http://static.artfulcode.net/newlisp/">Artful Code newLisp module repository</a>.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Submit article</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fa-better-mysql-module-for-newlisp%2F&amp;title=A+better+MySQL+module+for+newLISP" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fa-better-mysql-module-for-newlisp%2F&amp;title=A+better+MySQL+module+for+newLISP" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.dzone.com/links/add.html?description=A+better+MySQL+module+for+newLISP&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fa-better-mysql-module-for-newlisp%2F&amp;title=A+better+MySQL+module+for+newLISP" rel="nofollow" title="Add to&nbsp;DZone"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/dzone.png" title="Add to&nbsp;DZone" alt="Add to&nbsp;DZone" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fa-better-mysql-module-for-newlisp%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fa-better-mysql-module-for-newlisp%2F&amp;title=A+better+MySQL+module+for+newLISP" rel="nofollow" title="Add to&nbsp;reddit"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/reddit.png" title="Add to&nbsp;reddit" alt="Add to&nbsp;reddit" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fa-better-mysql-module-for-newlisp%2F&amp;title=A+better+MySQL+module+for+newLISP" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fa-better-mysql-module-for-newlisp%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+A+better+MySQL+module+for+newLISP+@+http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fa-better-mysql-module-for-newlisp%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.artfulcode.net/articles/a-better-mysql-module-for-newlisp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Full-text searching with MySQL</title>
		<link>http://www.artfulcode.net/articles/full-text-searching-mysql/</link>
		<comments>http://www.artfulcode.net/articles/full-text-searching-mysql/#comments</comments>
		<pubDate>Wed, 08 Oct 2008 16:30:00 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.artfulcode.net/articles/full-text-searching-mysql/</guid>
		<description><![CDATA[MySQL&#8217;s full-text search functions provide a simple framework for an easily implemented, approximate site search. Many sites, written in an interpreted language and powered by MySQL, can use MySQL&#8217;s full-text search to avoid third party dependencies. The basics The basics of the MySQL full-text search functions are well-documented in the MySQL online documentation. For those [...]]]></description>
			<content:encoded><![CDATA[<p>MySQL&#8217;s full-text search functions provide a simple framework for an easily implemented, approximate site search.  Many sites, written in an interpreted language and powered by MySQL, can use MySQL&#8217;s full-text search to avoid third party dependencies.<span id="more-11"></span></p>
<h4>The basics</h4>
<p>The basics of the MySQL full-text search functions are <a href="http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html">well-documented</a> in the MySQL online documentation.  For those lacking patience, here is a quick rundown.</p>
<p>Full-text searching is somewhat akin to a <code>LIKE</code> condition, but is much faster, requiring a <code>FULLTEXT</code> index to be created for the table columns targeted in the search.  To search the <code>title</code> and <code>description</code> columns of a table, <code>entries</code>, the following statement would create the proper index:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> entries <span style="color: #993333; font-weight: bold;">ADD</span> FULLTEXT<span style="color: #66cc66;">&#40;</span>title<span style="color: #66cc66;">,</span> description<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>To search these columns for the text, &#8220;python threading,&#8221; the <code>MATCH...AGAINST</code> functions are used:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> id<span style="color: #66cc66;">,</span> MATCH<span style="color: #66cc66;">&#40;</span>title<span style="color: #66cc66;">,</span> description<span style="color: #66cc66;">&#41;</span> AGAINST <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'python threading'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> score
<span style="color: #993333; font-weight: bold;">FROM</span> entries
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> score <span style="color: #993333; font-weight: bold;">DESC</span></pre></div></div>

<p>Notice that we keep the result of the match.  The value returned is a float representing the relevance of the match.  The higher the number, the more relevant the match.</p>
<p>There are several caveats to the full-text search.  In particular, any words that are common between many entries are treated as noise and their relevance in any search is diminished.  This means that were every article in <code>entries</code> to be about threading in Python, searching for &#8220;python threading&#8221; may not return extremely relevant results.  Refer to the <a href="http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html">MySQL</a> docs for more information.</p>
<h4>The hard part</h4>
<p>If the content to be searched is not conveniently located in one table, things get more complex.  In this case, a method must be devised to create an intermediary table to contain the search target.</p>
<p>This might be accomplished with a cron script that aggregates the information nightly or using stored procedures to keep the target table updated.</p>
<h4>Refining results</h4>
<p>A common case is to weight the search to favor more recent results.  Assuming that each entry has a <code>DATETIME</code> field named <code>timestamp</code>, this is easily accomplished by using the entry&#8217;s age to modify the score.</p>
<p>For an even reduction to the score based on the article&#8217;s age, divide the score by the age, which is determined with <code>DATEDIFF(NOW(), timestamp)</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>MATCH<span style="color: #66cc66;">&#40;</span>title<span style="color: #66cc66;">,</span> description<span style="color: #66cc66;">&#41;</span> AGAINST <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'python threading'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span>GREATEST<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> DATEDIFF<span style="color: #66cc66;">&#40;</span>NOW<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> timestamp<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Since <code>DATEDIFF</code> returns the difference in days, an entry written today could cause division by zero.<br />
<code>GREATEST</code> means that entries written today and yesterday have equal weight, but prevents results from omitting today&#8217;s articles.</p>
<p>A quick test of this will show that results become wildly incorrect after a few days as the text match score begins to diminish further with age.  This effect can be reduced by taking the <code>LOG</code> of the age, making the divisor increase less and less the greater the age.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">LOG<span style="color: #66cc66;">&#40;</span>GREATEST<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> DATEDIFF<span style="color: #66cc66;">&#40;</span>NOW<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> timestamp<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>The use of <code>LOG</code> causes a steep drop initially, smothing over time.  For a less dramatic effect, substituting the square root causes a similar drop in the weight of the entry&#8217;s age over time, but diminishing less starkly over time and without the initial steep drop.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">SQRT<span style="color: #66cc66;">&#40;</span>GREATEST<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> DATEDIFF<span style="color: #66cc66;">&#40;</span>NOW<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> timestamp<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>The complete SQL statement is now:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> id<span style="color: #66cc66;">,</span>
  <span style="color: #66cc66;">&#40;</span>MATCH<span style="color: #66cc66;">&#40;</span>title<span style="color: #66cc66;">,</span> description<span style="color: #66cc66;">&#41;</span> AGAINST <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'python threading'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span>SQRT<span style="color: #66cc66;">&#40;</span>GREATEST<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> DATEDIFF<span style="color: #66cc66;">&#40;</span>NOW<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> timestamp<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #993333; font-weight: bold;">AS</span> score
<span style="color: #993333; font-weight: bold;">FROM</span> entries
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> score <span style="color: #993333; font-weight: bold;">DESC</span></pre></div></div>

<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Submit article</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Ffull-text-searching-mysql%2F&amp;title=Full-text+searching+with+MySQL" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Ffull-text-searching-mysql%2F&amp;title=Full-text+searching+with+MySQL" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.dzone.com/links/add.html?description=Full-text+searching+with+MySQL&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Ffull-text-searching-mysql%2F&amp;title=Full-text+searching+with+MySQL" rel="nofollow" title="Add to&nbsp;DZone"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/dzone.png" title="Add to&nbsp;DZone" alt="Add to&nbsp;DZone" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Ffull-text-searching-mysql%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Ffull-text-searching-mysql%2F&amp;title=Full-text+searching+with+MySQL" rel="nofollow" title="Add to&nbsp;reddit"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/reddit.png" title="Add to&nbsp;reddit" alt="Add to&nbsp;reddit" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Ffull-text-searching-mysql%2F&amp;title=Full-text+searching+with+MySQL" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Ffull-text-searching-mysql%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Full-text+searching+with+MySQL+@+http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Ffull-text-searching-mysql%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.artfulcode.net/articles/full-text-searching-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Making 64-bit MySQL work with newLISP</title>
		<link>http://www.artfulcode.net/articles/making-64-bit-mysql-work-newlisp/</link>
		<comments>http://www.artfulcode.net/articles/making-64-bit-mysql-work-newlisp/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 17:49:47 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[newlisp]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.artfulcode.net/articles/making-64-bit-mysql-work-newlisp/</guid>
		<description><![CDATA[For the past few days have been spent trying to get the newLISP MySQL module to work with the 64-bit version of the libmysqlclient library. Here is what I did to get things working properly. Updating paths The file paths in the MySQL module only include the most common libmysqlclient paths. Update the files list [...]]]></description>
			<content:encoded><![CDATA[<p>For the past few days have been spent trying to get the newLISP MySQL module to work with the 64-bit version of the libmysqlclient library.  Here is what I did to get things working properly.<span id="more-16"></span></p>
<h4>Updating paths</h4>
<p>The file paths in the MySQL module only include the most common libmysqlclient paths.  Update the <code>files</code> list to contain <code>/usr/lib64</code> as well:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'files '<span style="color: #66cc66;">&#40;</span>
    <span style="color: #ff0000;">&quot;/usr/lib64/libmysqlclient.so&quot;</span> <span style="color: #808080; font-style: italic;">; 64 bit Linux, UNIX</span>
    <span style="color: #ff0000;">&quot;/usr/lib/libmysqlclient.so&quot;</span> <span style="color: #808080; font-style: italic;">; Linux, UNIX</span>
    <span style="color: #ff0000;">&quot;/usr/local/mysql/lib/libmysqlclient.dylib&quot;</span> <span style="color: #808080; font-style: italic;">; MacOS X</span>
<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>If you are not sure where you libmysqlclient library is, you can find it with this command (assuming it is somewhere in <code>/usr</code>):</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;">find /usr -<span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;libmysqlclient.so&quot;</span></pre></div></div>

<h4>Updating alignments</h4>
<p>The offsets for most structure fields are set at the beginning of mysql5.lsp.  They need to be updated:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>constant 'NUM_ROWS_OFFSET <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> big-endian <span style="color: #cc66cc;">4</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>constant 'NUM_FIELDS_OFFSET <span style="color: #cc66cc;">96</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>constant 'ERROR_OFFSET <span style="color: #cc66cc;">141</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>constant 'INSERT_ID_OFFSET <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> big-endian <span style="color: #cc66cc;">836</span> <span style="color: #cc66cc;">832</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>constant 'AFFECTED_ROWS_OFFSET <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> big-endian <span style="color: #cc66cc;">828</span> <span style="color: #cc66cc;">824</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>This is not necessarily the same on all systems.  In the newLISP source tree is a folder named util.  Compile sql.c and execute it to get the proper offsets.  Note that the numbers generated are only one of  the two used in this; you need to first determine the endianness of your system.  The module itself uses this newLISP form:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>pack <span style="color: #ff0000;">&quot;&gt;ld&quot;</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pack <span style="color: #ff0000;">&quot;ld&quot;</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>If that returns true, update the first number and offset the other number by -4.  Otherwise, update the second number and offset the first by 4 (except for <code>NUM_FIELDS_OFFSET</code> and <code>ERROR_OFFSET</code>).</p>
<p>The offsets for the MYSQL_FIELD structure fields are hard-coded in the functions <code>fetch-row</code> and <code>keep-type</code>.</p>
<p>In <code>keep-type</code>, update the line:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'data <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>+ type_ptr <span style="color: #66cc66;">&#40;</span>* <span style="color: #cc66cc;">19</span> <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>&#8230;to:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'data <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>+ type_ptr <span style="color: #66cc66;">&#40;</span>+ <span style="color: #66cc66;">&#40;</span>* <span style="color: #cc66cc;">9</span> <span style="color: #cc66cc;">8</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>* <span style="color: #cc66cc;">10</span> <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>That reflects that there are 9 8-byte fields (all char* or ulong) and 10 4-byte fields (all uint) in the MYSQL_FIELD struct.  That will keep the coerced types returned from queries straight.</p>
<p>Next, in <code>fetch-row</code>, the pointer to the field structure is found using:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'field_addr <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>+ rdata <span style="color: #66cc66;">&#40;</span>* field <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Change the 4 to 8:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'field_addr <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>+ rdata <span style="color: #66cc66;">&#40;</span>* field <span style="color: #cc66cc;">8</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>&#8230;or you will only get half the fields&#8217; values :).</p>
<h4>Data types</h4>
<p>On the newLISP forum, Lutz pointed out that in <code>fetch-row</code>, the call to <code>get-int</code> must be changed to <code>get-long</code> for the 64-bit library.  After a quick look at the types returned in the MySQL C api docs, I also updated <code>num-rows</code>, <code>affected-rows</code> and <code>inserted-id</code>.</p>
<h4>Test it out</h4>
<p>Load the updated module in the newLISP shell and run:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>test-mysql<span style="color: #66cc66;">&#41;</span></pre></div></div>

<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Submit article</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fmaking-64-bit-mysql-work-newlisp%2F&amp;title=Making+64-bit+MySQL+work+with+newLISP" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fmaking-64-bit-mysql-work-newlisp%2F&amp;title=Making+64-bit+MySQL+work+with+newLISP" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.dzone.com/links/add.html?description=Making+64-bit+MySQL+work+with+newLISP&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fmaking-64-bit-mysql-work-newlisp%2F&amp;title=Making+64-bit+MySQL+work+with+newLISP" rel="nofollow" title="Add to&nbsp;DZone"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/dzone.png" title="Add to&nbsp;DZone" alt="Add to&nbsp;DZone" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fmaking-64-bit-mysql-work-newlisp%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fmaking-64-bit-mysql-work-newlisp%2F&amp;title=Making+64-bit+MySQL+work+with+newLISP" rel="nofollow" title="Add to&nbsp;reddit"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/reddit.png" title="Add to&nbsp;reddit" alt="Add to&nbsp;reddit" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fmaking-64-bit-mysql-work-newlisp%2F&amp;title=Making+64-bit+MySQL+work+with+newLISP" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fmaking-64-bit-mysql-work-newlisp%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Making+64-bit+MySQL+work+with+newLISP+@+http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fmaking-64-bit-mysql-work-newlisp%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.artfulcode.net/articles/making-64-bit-mysql-work-newlisp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL library for newLISP</title>
		<link>http://www.artfulcode.net/articles/sql-library-newlisp/</link>
		<comments>http://www.artfulcode.net/articles/sql-library-newlisp/#comments</comments>
		<pubDate>Mon, 14 Jul 2008 21:24:35 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[foop]]></category>
		<category><![CDATA[functional]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[newlisp]]></category>
		<category><![CDATA[releases]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.artfulcode.net/articles/sql-library-newlisp/</guid>
		<description><![CDATA[The newLISP SQL library is a set of classes and functions to ease generation of SQL code in newLISP. The module is not yet feature-complete but is in a usable state. Much of the module uses the small convenience classes to &#8220;serialize&#8221; SQL expressions. Most of the module&#8217;s classes have :serialize methods that render the [...]]]></description>
			<content:encoded><![CDATA[<p>The newLISP SQL library is a set of classes and functions to ease generation of SQL code in newLISP.  The module is not yet feature-complete but is in a usable state.<span id="more-20"></span></p>
<p>Much of the module uses the small convenience classes to &#8220;serialize&#8221; SQL expressions.  Most of the module&#8217;s classes have <code>:serialize</code> methods that render the encapsulated data as a string.  For example, the <code>Field</code> class:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>f <span style="color: #66cc66;">&#40;</span>Field <span style="color: #ff0000;">&quot;table&quot;</span> <span style="color: #ff0000;">&quot;fieldname&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">serialize</span> f<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&amp;</span>gt<span style="color: #808080; font-style: italic;">; &quot;table.fieldname&quot;</span></pre></div></div>

<p>&#8230;or the <code>Condition</code> class:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>c <span style="color: #66cc66;">&#40;</span>Condition <span style="color: #ff0000;">&quot;&amp;gt;&quot;</span> <span style="color: #ff0000;">&quot;salary&quot;</span> <span style="color: #cc66cc;">65000</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">serialize</span> c<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&amp;</span>gt<span style="color: #808080; font-style: italic;">; &quot;salary &amp;gt; '65000'&quot;</span></pre></div></div>

<p>Note that values are enclosed in single quotes for ANSI compliance.  The most interesting function in the module, however, is <code>sql:expr</code>, which uses the <code>match</code>-based primitives in the <span style="text-decoration: line-through;">functional</span> module to generate various types of expressions:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>sql<span style="color: #66cc66;">:</span><span style="color: #555;">expr</span> <span style="color: #ff0000;">&quot;employees&quot;</span> <span style="color: #ff0000;">&quot;first_name&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&amp;</span>gt<span style="color: #808080; font-style: italic;">; &quot;employees.first_name&quot;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>sql<span style="color: #66cc66;">:</span><span style="color: #555;">expr</span> <span style="color: #ff0000;">&quot;LIKE&quot;</span> <span style="color: #ff0000;">&quot;first_name&quot;</span> <span style="color: #ff0000;">&quot;Stev%&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&amp;</span>gt<span style="color: #808080; font-style: italic;">; &quot;first_name LIKE 'Stev%'&quot;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>sql<span style="color: #66cc66;">:</span><span style="color: #555;">expr</span> <span style="color: #ff0000;">&quot;OR&quot;</span> <span style="color: #66cc66;">&#40;</span>sql<span style="color: #66cc66;">:</span><span style="color: #555;">expr</span> <span style="color: #ff0000;">&quot;LIKE&quot;</span> <span style="color: #ff0000;">&quot;first_name&quot;</span> <span style="color: #ff0000;">&quot;Stev%&quot;</span><span style="color: #66cc66;">&#41;</span>
               <span style="color: #66cc66;">&#40;</span>sql<span style="color: #66cc66;">:</span><span style="color: #555;">expr</span> <span style="color: #ff0000;">&quot;LIKE&quot;</span> <span style="color: #ff0000;">&quot;last_name&quot;</span> <span style="color: #ff0000;">&quot;John%&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&amp;</span>gt<span style="color: #808080; font-style: italic;">; &quot;((first_name LIKE 'Stev%') OR (last_name LIKE 'John%'))&quot;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>sql<span style="color: #66cc66;">:</span><span style="color: #555;">expr</span> <span style="color: #cc66cc;">6</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&amp;</span>gt<span style="color: #808080; font-style: italic;">;&quot;6&quot;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>sql<span style="color: #66cc66;">:</span><span style="color: #555;">expr</span> 'myapp<span style="color: #66cc66;">:</span><span style="color: #555;">employees</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&amp;</span>gt<span style="color: #808080; font-style: italic;">; &quot;employees&quot;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>sql<span style="color: #66cc66;">:</span><span style="color: #555;">expr</span> <span style="color: #ff0000;">&quot;CONV&quot;</span> <span style="color: #ff0000;">&quot;AF&quot;</span> <span style="color: #cc66cc;">16</span> <span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&amp;</span>gt<span style="color: #808080; font-style: italic;">; &quot;CONV('AF',16,10)&quot;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>sql<span style="color: #66cc66;">:</span><span style="color: #555;">expr</span> <span style="color: #ff0000;">&quot;LIKE&quot;</span> <span style="color: #66cc66;">&#40;</span>sql<span style="color: #66cc66;">:</span><span style="color: #555;">expr</span> <span style="color: #ff0000;">&quot;employees&quot;</span> <span style="color: #ff0000;">&quot;first_name&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;Stev%&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&amp;</span>gt<span style="color: #808080; font-style: italic;">; &quot;employees.first_name LIKE 'Stev%'&quot;</span></pre></div></div>

<p>Additional functions directly express <code>select</code>, <code>update</code>, <code>insert</code>, and <code>delete</code> statements or handle data type conversions (such as parsing SQL datetimes).</p>
<h4>Functional</h4>
<p>Another addition to Artful Code&#8217;s module list is the <span style="text-decoration: line-through;">functional</span> module.  This library provides some basic conditionals that make use of <code>match</code> to process data.  These macros express program logic by associating blocks of code with the structure of data.</p>
<p>Here is an example using <code>match-case</code>. <code>match-case</code> accepts a single expression and a series of forms that describe what to do based on its structure.  Each case form consists of a <a href="http://www.newlisp.org/downloads/newlisp_manual.html#match">match expression</a>, a list of variables to be locally bound to the result of the match, and an individual form to evaluate in a local scope with the matched variables bound:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x '<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">3</span> <span style="color: #cc66cc;">4</span> <span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>match-<span style="color: #b1b100;">case</span> x
        <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>? ? ?<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>a b c<span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>println <span style="color: #ff0000;">&quot;a b and c do not get bound here, because they do not match x&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>? ? ? *<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>a b c d<span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>println <span style="color: #ff0000;">&quot;a = 1, b = 2, c = 3, and d = '(4 5)&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Here, the second block would match because <code>(? ? ? *)</code> matches against <code>(1 2 3 4 5)</code> and creates the binding association, <code>((a 1) (b 2) (c 3) (d (4 5)))</code>.</p>
<p>Also included in the module is <code>match-cond</code>, which is more powerful than <code>match-case</code>. <code>match-cond</code> works like <code>cond</code>, except that instead of a user-defined conditional, the first form in each case is a list of <code>pattern</code>, <code>symbol-list</code>, and <code>target</code>.  See the <span style="text-decoration: line-through;">documentation</span> for more details.</p>
<p><strong>Edit (2009-02-16): the functional module in mentioned in this post has been replaced with the <a href="http://static.artfulcode.net/newlisp/matching.lsp.html">matching</a> module.</strong></p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Submit article</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fsql-library-newlisp%2F&amp;title=SQL+library+for+newLISP" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fsql-library-newlisp%2F&amp;title=SQL+library+for+newLISP" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.dzone.com/links/add.html?description=SQL+library+for+newLISP&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fsql-library-newlisp%2F&amp;title=SQL+library+for+newLISP" rel="nofollow" title="Add to&nbsp;DZone"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/dzone.png" title="Add to&nbsp;DZone" alt="Add to&nbsp;DZone" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fsql-library-newlisp%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fsql-library-newlisp%2F&amp;title=SQL+library+for+newLISP" rel="nofollow" title="Add to&nbsp;reddit"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/reddit.png" title="Add to&nbsp;reddit" alt="Add to&nbsp;reddit" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fsql-library-newlisp%2F&amp;title=SQL+library+for+newLISP" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fsql-library-newlisp%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+SQL+library+for+newLISP+@+http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fsql-library-newlisp%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.artfulcode.net/articles/sql-library-newlisp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updating the newLISP MySQL5 module</title>
		<link>http://www.artfulcode.net/articles/updating-newlisp-mysql5-module/</link>
		<comments>http://www.artfulcode.net/articles/updating-newlisp-mysql5-module/#comments</comments>
		<pubDate>Wed, 01 Aug 2007 20:55:00 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[newlisp]]></category>

		<guid isPermaLink="false">http://www.artfulcode.net/articles/updating-newlisp-mysql5-module/</guid>
		<description><![CDATA[It has been a very busy few weeks here. This is the time of year when work gets very rushed, and on top of that, my wife and I are expecting. Due to all of that, I have decided against finishing the C Libraries tutorial for newLisp at this time. The reason that I had [...]]]></description>
			<content:encoded><![CDATA[<p>It has been a very busy few weeks here.  This is the time of year when work gets very rushed, and on top of that, my wife and I are expecting.  Due to all of that, I have decided against finishing the C Libraries tutorial for newLisp at this time.  The reason that I had worked on it to begin with was to attempt a better MySQL module than the current mysql5.lsp module that comes with the newLisp distribution, but due to time constraints, I have instead written some alterations to the current one that provide many of the same features that I was looking for initially, and fixing a few of the more superficial and crucial problems that I found in the library (in particular, fetch-all&#8217;s habit of leaving around old result sets without clearing the data by using a context-global variable for storage, rather than a local variable).<span id="more-50"></span></p>
<p>New features in this version of the module:</p>
<ul>
<li> Fixed fetch-all to use a local variable to prevent alteration of future result sets</li>
<li> num-fields: returns the number of columns in the result set</li>
<li> result-fields: returns a list of columns&#8217; field-names for the current result set</li>
<li> fetch-table: maps the column field names to the row data<br />
*add-path: adds a path to an internal list of paths that init will search for the mysql client library</li>
<li> Added several default paths:
<ul>
<li> /usr/lib/libmysqlclient.so</li>
<li> /usr/local/mysql/lib/libmysqlclient.dylib</li>
<li> C:mysqllibmysqlclient.dll</li>
</ul>
</li>
</ul>
<p>Caveats:</p>
<ul>
<li> Broke documentation module by using lisp-style function documentation (inline docs and comments) and deleting Lutz&#8217;s documentation for my own fiendish reasons (I can see more code while I&#8217;m working on the source).  If I get around to making my changes more professional, I will restore the documentation for the module.</li>
<li> fetch-table is perhaps not quite as optimized as it could be; as it is, it takes nearly twice the time to create the results list as a normal fetch-all operation</li>
</ul>
<p>I will also make this available on its own page on the site.  Now, without further ado:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>context 'MySQL<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; following constant offsets into 'C' data structures are different on each</span>
<span style="color: #808080; font-style: italic;">; major MySQL version compile and run util/sql.c from the distribution to</span>
<span style="color: #808080; font-style: italic;">; obtain these numbers</span>
&nbsp;
<span style="color: #808080; font-style: italic;">; check endianess of the host CPU</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'big-endian <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>pack <span style="color: #ff0000;">&quot;&amp;gt;ld&quot;</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pack <span style="color: #ff0000;">&quot;ld&quot;</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>constant 'NUM_ROWS_OFFSET <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> big-endian <span style="color: #cc66cc;">4</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>constant 'NUM_FIELDS_OFFSET <span style="color: #cc66cc;">60</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>constant 'ERROR_OFFSET <span style="color: #cc66cc;">85</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>constant 'INSERT_ID_OFFSET <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> big-endian <span style="color: #cc66cc;">708</span> <span style="color: #cc66cc;">704</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>constant 'AFFECTED_ROWS_OFFSET <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> big-endian <span style="color: #cc66cc;">700</span> <span style="color: #cc66cc;">696</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>init<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'MYSQL <span style="color: #66cc66;">&#40;</span>mysql_init <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> MYSQL <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'MYSQL <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> MYSQL <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>connect host user passw database<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>mysql_real_connect MYSQL host user passw database <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>MySQL<span style="color: #66cc66;">:</span><span style="color: #555;">query</span> sql<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> MYSQL_RES <span style="color: #66cc66;">&#40;</span>mysql_free_result MYSQL_RES<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'result  <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>mysql_query MYSQL sql<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'MYSQL_RES <span style="color: #66cc66;">&#40;</span>mysql_store_result MYSQL<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> MYSQL_RES <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'MYSQL_RES <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> result <span style="color: #66cc66;">&#40;</span>find <span style="color: #ff0000;">&quot;insert into&quot;</span> sql <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'result <span style="color: #66cc66;">&#40;</span>inserted-id<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  result<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>num-rows<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> MYSQL_RES <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>+ MYSQL_RES NUM_ROWS_OFFSET<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>num-fields<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> MYSQL_RES <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>+ MYSQL_RES NUM_FIELDS_OFFSET<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>keep-type res_ptr field_addr column_num<span style="color: #66cc66;">,</span> data<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'type_ptr <span style="color: #66cc66;">&#40;</span>mysql_fetch_field_direct res_ptr <span style="color: #66cc66;">&#40;</span>int column_num<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">; The field type is the 20th field of the MySQL_FIELD structure</span>
  <span style="color: #808080; font-style: italic;">; since fields 1-19 are all 4 byte fields we get the enum value</span>
  <span style="color: #808080; font-style: italic;">; like so</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'data <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>+ type_ptr <span style="color: #66cc66;">&#40;</span>* <span style="color: #cc66cc;">19</span> <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">; Consult 'enum_field_types' in mysql_com.h for values</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> data <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; boolean</span>
        <span style="color: #66cc66;">&#40;</span>get-string field_addr<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> data <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; integer</span>
        <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>get-string field_addr<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> data <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; datetime</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">apply</span> date-<span style="color: #b1b100;">value</span> <span style="color: #66cc66;">&#40;</span>map int <span style="color: #66cc66;">&#40;</span>parse <span style="color: #66cc66;">&#40;</span>get-string field_addr<span style="color: #66cc66;">&#41;</span> <span style="color: #ff0000;">&quot;[-: ]&quot;</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> data <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; float</span>
        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">float</span> <span style="color: #66cc66;">&#40;</span>get-string field_addr<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #808080; font-style: italic;">; else (will handle TEXT type 252)</span>
      <span style="color: #66cc66;">&#40;</span>get-string field_addr<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>fetch-row<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> MYSQL_RES
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'rdata <span style="color: #66cc66;">&#40;</span>mysql_fetch_row MYSQL_RES<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'rdata <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!=</span> rdata <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>begin
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'row '<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">dotimes</span> <span style="color: #66cc66;">&#40;</span>field <span style="color: #66cc66;">&#40;</span>num-fields<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'field_addr <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>+ rdata <span style="color: #66cc66;">&#40;</span>* field <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> field_addr <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span>push <span style="color: #b1b100;">nil</span> row -<span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; what to do when the field contains NULL</span>
              <span style="color: #66cc66;">&#40;</span>push <span style="color: #66cc66;">&#40;</span>keep-type MYSQL_RES field_addr field<span style="color: #66cc66;">&#41;</span> row -<span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    row<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>fetch-all<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">dotimes</span> <span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>num-rows<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>push <span style="color: #66cc66;">&#40;</span>fetch-row<span style="color: #66cc66;">&#41;</span> all<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">reverse</span> all<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>databases<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>query <span style="color: #ff0000;">&quot;show databases;&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>fetch-all<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>tables<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>query <span style="color: #ff0000;">&quot;show tables;&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>fetch-all<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>fields table<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>query <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">append</span> <span style="color: #ff0000;">&quot;show fields from &quot;</span> table <span style="color: #ff0000;">&quot;;&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>fetch-all<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>data-seek offset<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> MYSQL_RES
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> big-endian
        <span style="color: #66cc66;">&#40;</span>mysql_data_seek MYSQL_RES  <span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">&#40;</span>int offset<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>mysql_data_seek MYSQL_RES <span style="color: #66cc66;">&#40;</span>int offset<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  true
<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">error</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> MYSQL <span style="color: #66cc66;">&#40;</span>get-string <span style="color: #66cc66;">&#40;</span>+ MYSQL ERROR_OFFSET<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>affected-rows<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> MYSQL
    <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>+ MYSQL AFFECTED_ROWS_OFFSET<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>inserted-id<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> MYSQL <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>int <span style="color: #66cc66;">&#40;</span>+ MYSQL INSERT_ID_OFFSET<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>escape <span style="color: #b1b100;">value</span> <span style="color: #66cc66;">,</span> safe-<span style="color: #b1b100;">value</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'safe-<span style="color: #b1b100;">value</span> <span style="color: #66cc66;">&#40;</span>dup <span style="color: #ff0000;">&quot; &quot;</span> <span style="color: #66cc66;">&#40;</span>+ <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">length</span> <span style="color: #b1b100;">value</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>MySQL<span style="color: #66cc66;">:</span><span style="color: #555;">mysql_real_escape_string</span> MySQL<span style="color: #66cc66;">:</span><span style="color: #555;">MYSQL</span> safe-<span style="color: #b1b100;">value</span> <span style="color: #b1b100;">value</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">length</span> <span style="color: #b1b100;">value</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  safe-<span style="color: #b1b100;">value</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>close-db<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> MYSQL_RES <span style="color: #66cc66;">&#40;</span>mysql_free_result MYSQL_RES<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> MYSQL <span style="color: #66cc66;">&#40;</span>mysql_close MYSQL<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'MYSQL <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'MYSQL_RES <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
  true<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;;; My additions</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'lib-paths '<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;/usr/lib/libmysqlclient.so&quot;</span> <span style="color: #808080; font-style: italic;">; linux</span>
                  <span style="color: #ff0000;">&quot;/usr/local/mysql/lib/libmysqlclient.dylib&quot;</span> <span style="color: #808080; font-style: italic;">; osx</span>
                  <span style="color: #ff0000;">&quot;C:<span style="color: #000099; font-weight: bold;">\\</span>mysql<span style="color: #000099; font-weight: bold;">\\</span>lib<span style="color: #000099; font-weight: bold;">\\</span>mysqlclient.dll&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">; win32</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>add-path str-path<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Pushes new path on to lib-paths, our list of paths to search for the
  mysql client library.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>push str-path lib-paths<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>init<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Attempts to initialize the module.&quot;</span>
  <span style="color: #808080; font-style: italic;">;; New init actions</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">dolist</span> <span style="color: #66cc66;">&#40;</span>lib lib-paths<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>file? lib<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'libmysqlclient lib<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_init&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_real_connect&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_get_host_info&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_real_escape_string&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_query&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_real_query&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_store_result&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_free_result&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_data_seek&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_fetch_row&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_close&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_fetch_field_direct&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_insert_id&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_num_fields&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>import libmysqlclient <span style="color: #ff0000;">&quot;mysql_fetch_field&quot;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #808080; font-style: italic;">;; Perform previous definition's actions</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'MYSQL <span style="color: #66cc66;">&#40;</span>mysql_init <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> MYSQL <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">set</span> 'MYSQL <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> MYSQL <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>fetch-all <span style="color: #66cc66;">,</span> all<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Redefined fetch-all that is not affected by previous results, nor does it
  affect future results.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">dotimes</span> <span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>num-rows<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>push <span style="color: #66cc66;">&#40;</span>fetch-row<span style="color: #66cc66;">&#41;</span> all<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">reverse</span> all<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>num-fields<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Evaluates the total number of fields for the current result.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>mysql_num_fields MYSQL_RES<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>result-fields<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Generates a list of strings reflecting the names of the fields in the
  current result.&quot;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>fields '<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">dotimes</span> <span style="color: #66cc66;">&#40;</span>i <span style="color: #66cc66;">&#40;</span>num-fields<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>push <span style="color: #66cc66;">&#40;</span>get-string <span style="color: #66cc66;">&#40;</span>get-int <span style="color: #66cc66;">&#40;</span>mysql_fetch_field MYSQL_RES<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
               fields -<span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> fields<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>define <span style="color: #66cc66;">&#40;</span>fetch-table<span style="color: #66cc66;">&#41;</span>
  <span style="color: #ff0000;">&quot;Creates a table associating field names with field values for the current
  result.  This will not work if the result has already been pulled another
  way.&quot;</span>
  <span style="color: #66cc66;">&#40;</span>letn <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>rows <span style="color: #66cc66;">&#40;</span>fetch-all<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>fields <span style="color: #66cc66;">&#40;</span>result-fields<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>pair <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>row<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>map <span style="color: #b1b100;">list</span> fields row<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>map pair rows<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>context 'MAIN<span style="color: #66cc66;">&#41;</span></pre></div></div>

<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Submit article</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fupdating-newlisp-mysql5-module%2F&amp;title=Updating+the+newLISP+MySQL5+module" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fupdating-newlisp-mysql5-module%2F&amp;title=Updating+the+newLISP+MySQL5+module" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.dzone.com/links/add.html?description=Updating+the+newLISP+MySQL5+module&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fupdating-newlisp-mysql5-module%2F&amp;title=Updating+the+newLISP+MySQL5+module" rel="nofollow" title="Add to&nbsp;DZone"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/dzone.png" title="Add to&nbsp;DZone" alt="Add to&nbsp;DZone" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fupdating-newlisp-mysql5-module%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fupdating-newlisp-mysql5-module%2F&amp;title=Updating+the+newLISP+MySQL5+module" rel="nofollow" title="Add to&nbsp;reddit"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/reddit.png" title="Add to&nbsp;reddit" alt="Add to&nbsp;reddit" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fupdating-newlisp-mysql5-module%2F&amp;title=Updating+the+newLISP+MySQL5+module" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fupdating-newlisp-mysql5-module%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Updating+the+newLISP+MySQL5+module+@+http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fupdating-newlisp-mysql5-module%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.artfulcode.net/articles/updating-newlisp-mysql5-module/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wrapping a C library in lisp (part 2)</title>
		<link>http://www.artfulcode.net/articles/wrapping-c-library-lisp-part-2/</link>
		<comments>http://www.artfulcode.net/articles/wrapping-c-library-lisp-part-2/#comments</comments>
		<pubDate>Wed, 04 Jul 2007 00:53:00 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.artfulcode.net/articles/wrapping-c-library-lisp-part-2/</guid>
		<description><![CDATA[Once the library has been defined and loaded into the Lisp image, work can begin on defining C routines in Lisp. Before that can be done, however, a note for those who do not know C. Functions in C have a declared type, as do all of their arguments. When reading the docs for a [...]]]></description>
			<content:encoded><![CDATA[<p>Once the library has been defined and loaded into the Lisp image, work can begin on defining C routines in Lisp.<span id="more-52"></span></p>
<p>Before that can be done, however, a note for those who do not know C.  Functions in C have a declared type, as do all of their arguments.  When reading the docs for a particular library, you will want to know description conventions for C routines.  Let&#8217;s use the example of mysql_init() to begin with.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">MYSQL <span style="color: #339933;">*</span>mysql_init<span style="color: #009900;">&#40;</span>MYSQL <span style="color: #339933;">*</span>mysql<span style="color: #009900;">&#41;</span></pre></div></div>

<p>The first part, <code>MYSQL *mysql_init</code>, defines the function&#8217;s return type and name.  MYSQL is a type created by the library that stores a struct.  This is actually completely irrelevant at this point, because of the asterisk.  The asterisk means that the function is actually allocating a pointer.  Although we can pass an already existing MYSQL object pointer (that&#8217;s the second part), generally we will just use this function to create the internal struct needed to run the program.  We will need to store the pointer that is returned.</p>
<p>The second part, <code>MYSQL *mysql</code>, states this- namely, that a pointer (named mysql, and we know it&#8217;s a pointer because it&#8217;s labelled with an asterisk- *mysql) will be returned.  We store it because this will be passed to most of the other routines in the library.</p>
<p>Technically, we do not really need to define the routine in Lisp.  The function, foreign-funcall, allows us to call the foreign function directly.</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>foreign-<span style="color: #b1b100;">funcall</span> <span style="color: #ff0000;">&quot;mysql_init&quot;</span> <span style="color: #66cc66;">:</span><span style="color: #555;">pointer</span> <span style="color: #66cc66;">&#40;</span>null-pointer<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">:</span><span style="color: #555;">pointer</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>In this, we apply mysql_init to a null pointer (an empty pointer argument), created using the CFFI function (null-pointer).  The last symbol states we will get a pointer back.</p>
<p>In order to wrap this as a pretty Lisp function, we do:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defcfun <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;mysql_init&quot;</span> libmysql-init<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">:</span><span style="color: #555;">pointer</span>
  <span style="color: #66cc66;">&#40;</span>mysql <span style="color: #66cc66;">:</span><span style="color: #555;">pointer</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>This points the Lisp symbol libmysql-init to &#8220;mysql_init&#8221; in the C library.  The next argument, :pointer, states that this returns a pointer.  Next, we can have an &amp;rest list of (parameter-name :type), to define the parameters to pass to the function, in this case, (mysql :pointer).  Available types are listed in the <a href="http://common-lisp.net/project/cffi/manual/cffi-manual.html#Built_002dIn-Types">CFFI documentation</a>.</p>
<p>However, we don&#8217;t want to have to run (null-pointer) every time we use this function.  We also need to store the return value for future use.  So let&#8217;s wrap it in another function to make it more expressive:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> mysql-init <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> *mysql* <span style="color: #66cc66;">&#40;</span>libmysql-init <span style="color: #66cc66;">&#40;</span>null-pointer<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">or</span> *mysql* <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> *mysql* <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Now, we can simply run (mysql-init) and we will have the symbol *mysql* pointing to the returned pointer or nil in the event of a failure.</p>
<p>If we do have a failure, we can use the following definitions to get at the error text:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defcfun <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;mysql_error&quot;</span> libmysql-<span style="color: #b1b100;">error</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">:</span><span style="color: #555;">string</span>
    <span style="color: #66cc66;">&#40;</span>mysql <span style="color: #66cc66;">:</span><span style="color: #555;">pointer</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> mysql-<span style="color: #b1b100;">error</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>libmysql-<span style="color: #b1b100;">error</span> *mysql*<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Of course, we will want to add error handling and some other niceties, but having these declared makes writing and testing those completed functions that much easier.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Submit article</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-2%2F&amp;title=Wrapping+a+C+library+in+lisp+%28part+2%29" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-2%2F&amp;title=Wrapping+a+C+library+in+lisp+%28part+2%29" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.dzone.com/links/add.html?description=Wrapping+a+C+library+in+lisp+%28part+2%29&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-2%2F&amp;title=Wrapping+a+C+library+in+lisp+%28part+2%29" rel="nofollow" title="Add to&nbsp;DZone"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/dzone.png" title="Add to&nbsp;DZone" alt="Add to&nbsp;DZone" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-2%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-2%2F&amp;title=Wrapping+a+C+library+in+lisp+%28part+2%29" rel="nofollow" title="Add to&nbsp;reddit"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/reddit.png" title="Add to&nbsp;reddit" alt="Add to&nbsp;reddit" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-2%2F&amp;title=Wrapping+a+C+library+in+lisp+%28part+2%29" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-2%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Wrapping+a+C+library+in+lisp+%28part+2%29+@+http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-2%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.artfulcode.net/articles/wrapping-c-library-lisp-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wrapping a C library in lisp (part 1)</title>
		<link>http://www.artfulcode.net/articles/wrapping-c-library-lisp-part-1/</link>
		<comments>http://www.artfulcode.net/articles/wrapping-c-library-lisp-part-1/#comments</comments>
		<pubDate>Mon, 02 Jul 2007 19:06:00 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.artfulcode.net/articles/wrapping-c-library-lisp-part-1/</guid>
		<description><![CDATA[One of the more significant difficulties I face when developing Lisp applications is the apparent lack of generally compatable database libraries for the various lisp dialects. CLSQL is a nice solution, but it does not get along well on OSX, my development OS, or with CLISP, which is the primary lisp dialect I have available [...]]]></description>
			<content:encoded><![CDATA[<p>One of the more significant difficulties I face when developing Lisp applications is the apparent lack of generally compatable database libraries for the various lisp dialects. <a href="http://clsql.b9.com/">CLSQL</a> is a nice solution, but it does not get along well on OSX, my development OS, or with CLISP, which is the primary lisp dialect I have available on my <a href="http://www.nearlyfreespeech.com">host</a>.<span id="more-53"></span></p>
<p>My database of choice (and the one available to me on my host) is MySQL. Unfortunately, this is the piece of CLSQL that I can&#8217;t seem to get running on OSX.  In every dialect I&#8217;ve tried (sbcl, cmucl, clisp, openmcl, ad infinitum), CFFI/UFFI cannot find the libmysqlclient library- even when it has been pushed onto the library search path&#8230; but that is a rant for a different blog (or Usenet).</p>
<p><a href="http://common-lisp.net/project/cffi/">CFFI</a> is generally available via ASDF and plays well with GNU CLISP.  It has a fairly simple, intuitive syntax for making C routines available to lisp (as a side note, I have not encountered anything as easy as newLisp&#8217;s C library importer, although this is made easier in that newLisp is implemented in C).</p>
<p>Using CFFI, we can fairly easily create mappings for the most important <a href="http://dev.mysql.com/doc/refman/5.0/en/c.html">MySQL C api</a> functions.  This entry will walk through the process of importing the library; future entries will go one to defining a few of the most basic routines for our lisp image.</p>
<p>Let&#8217;s begin by defining our mysql wrapper package.</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defpackage <span style="color: #66cc66;">:</span><span style="color: #555;">mysql-api</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">use</span> <span style="color: #66cc66;">:</span><span style="color: #555;">common-lisp</span> <span style="color: #66cc66;">:</span><span style="color: #555;">cffi</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>in-package <span style="color: #66cc66;">:</span><span style="color: #555;">mysql-api</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>To load the library itself, we use the function, define-foreign-library, in the CFFI package.  The first argument to define-foreign-library is the symbol we wish to point to the library.  Next, we create list similar in syntax to cond, where we define the names of our libraries based on, for example, the host OS.  Since I happen to know that CFFI does find the library path even when explicitly specified, we can conveniently specify a list of full paths to try for each OS.  The full list of platform symbols available <a href="http://common-lisp.net/project/cffi/manual/cffi-manual.html#Platform_002dspecific-features">here</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>define-foreign-library libmysqlclient
  <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">darwin</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">or</span> <span style="color: #ff0000;">&quot;/usr/local/mysql/lib/libmysqlclient.dylib&quot;</span>
                <span style="color: #ff0000;">&quot;/sw/lib/libmysqlclient.dylib&quot;</span>
                <span style="color: #ff0000;">&quot;/usr/local/lib/libmysqlclient.dylib&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>t <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">default</span> <span style="color: #ff0000;">&quot;libmysqlclient&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>The last line is a catch-all, and will format the filename based on the OS (i.e., libmysqlclient.so for unix, .dll for Windows).  Although I know my library is located in /usr/local/mysql/lib, I have included various other commonly used paths for MySQL libraries in OSX.</p>
<p>Then, to load the library:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>use-foreign-library libmysqlclient<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>This will return a pointer to a foreign address (for the C-challenged, a pointer is a variable to points to a value&#8217;s address in memory; it is used to access a value by reference, rather than by value) or, in the event that it did not work, it will throw up an error.  Generally, the error will be caused by CFFI not being able to find the library. If this is the case, verify that your account has access to the file and that the file is included in one of the paths above.</p>
<p>Next, we will begin defining our C routines in lisp.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a><strong><em>Submit article</em></strong></a>
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-1%2F&amp;title=Wrapping+a+C+library+in+lisp+%28part+1%29" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-1%2F&amp;title=Wrapping+a+C+library+in+lisp+%28part+1%29" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.dzone.com/links/add.html?description=Wrapping+a+C+library+in+lisp+%28part+1%29&amp;url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-1%2F&amp;title=Wrapping+a+C+library+in+lisp+%28part+1%29" rel="nofollow" title="Add to&nbsp;DZone"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/dzone.png" title="Add to&nbsp;DZone" alt="Add to&nbsp;DZone" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-1%2F" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-1%2F&amp;title=Wrapping+a+C+library+in+lisp+%28part+1%29" rel="nofollow" title="Add to&nbsp;reddit"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/reddit.png" title="Add to&nbsp;reddit" alt="Add to&nbsp;reddit" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-1%2F&amp;title=Wrapping+a+C+library+in+lisp+%28part+1%29" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-1%2F" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Wrapping+a+C+library+in+lisp+%28part+1%29+@+http%3A%2F%2Fwww.artfulcode.net%2Farticles%2Fwrapping-c-library-lisp-part-1%2F" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://www.artfulcode.net/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.artfulcode.net/articles/wrapping-c-library-lisp-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

