<div dir="ltr"><div style>Alexey,</div>Regarding named parameters - another option is to use numbered parameters like :1, :2 etc. It will help with repeated parameters at least. I didn&#39;t understandthe first Bardur&#39;s point about  &quot;different SQL strings&quot; though.<div>
<br></div><div style>Kind regards,</div><div style>Kirill Zaborsky</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/7/31 Alexey Uimanov <span dir="ltr">&lt;<a href="mailto:s9gf4ult@gmail.com" target="_blank">s9gf4ult@gmail.com</a>&gt;</span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

Regard parameterized SQL: It might be worth using named parameters (e.g.<br>
&quot;:foo&quot; and &quot;:bar&quot; or something like that) rather than &quot;?&quot; as<br>
placeholders in SQL/prepared SQL. This will make it slightly more<br>
flexible if you need to provide different SQL strings for different<br>
databases, but want to reuse the code which does the actual running of<br>
the SQL. It&#39;s also more flexible if you need to repeat parameters -- the<br>
latter is typical with PostgreSQL if you want to emulate<br>
&quot;update-or-insert&quot; in a single SQL statement<br></blockquote><div><br></div><div>Named parameters might be more flexible, but it is need to think hard about how to implement this.</div><div>If you are using named parameters you need to pass not just list [SqlValue] as parameters, </div>

<div>but Map Text SqlValue or something. So named parameters will not be compatible with unnamed and will need</div><div>separate query parser.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


Regarding migrations: If you haven&#39;t already, please have a look at<br>
Liquibase (<a href="http://www.liquibase.org/documentation/index.html" target="_blank">http://www.liquibase.org/documentation/index.html</a>) before<br>
attempting to implement migrations. The most important attributes of<br>
Liquibase are:<br></blockquote><div><br></div><div>What I am trying to implement is not a new migration system, but just the common interface for <br></div><div>simple schema actions, here is my in-mind draft:</div>
<div><br></div><div><font face="courier new, monospace">newtype TableName = TableName Text</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">data TableDescription = TableDescription </font></div>

<div><font face="courier new, monospace">                        {tableName :: TableName </font></div><div><font face="courier new, monospace">                        ,tableFields :: [FieldDescription]</font></div>
<div><span style="font-family:&#39;courier new&#39;,monospace">                        }</span><br></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">class (Connection con) =&gt; Introspect con where</font></div>

<div><font face="courier new, monospace">  getTableNames:: con -&gt; IO [</font><span style="font-family:&#39;courier new&#39;,monospace">TableName</span><font face="courier new, monospace">]</font></div><div>
<font face="courier new, monospace">  describeTable :: con -&gt; </font><span style="font-family:&#39;courier new&#39;,monospace">TableName</span><font face="courier new, monospace"> -&gt; IO TableDescription</font></div>

<div><font face="courier new, monospace">  getIndexes :: con -&gt; [IndexDescription]</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">class (Connection con) =&gt; SchemaChange con where</font></div>

<div><font face="courier new, monospace">  createTable :: con -&gt; TableDescription -&gt; IO ()</font></div><div><font face="courier new, monospace">  dropTable :: con -&gt; </font><span style="font-family:&#39;courier new&#39;,monospace">TableName</span><font face="courier new, monospace"> -&gt; IO ()</font></div>

<div><font face="courier new, monospace">  addColumn :: con -&gt; </font><span style="font-family:&#39;courier new&#39;,monospace">TableName</span><font face="courier new, monospace"> -&gt; FieldDescription -&gt; IO ()</font></div>

<div><font face="courier new, monospace">  ...............</font></div><div><br></div><div>This typeclasses must provide database-independent schema introspection and changing. </div><div>Migration system can be anything you want.</div>

<div><br></div><div><font face="arial, helvetica, sans-serif">I also have the idea do not throw the exceptions in IO but return  (Either SqlError a) from </font></div><div><font face="arial, helvetica, sans-serif">all the Connection and Statement methods for safe data processing. What do you think about ?</font></div>

</div></div></div>
<br>_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br>--<br>
You received this message because you are subscribed to a topic in the Google Groups &quot;Haskell-cafe&quot; group.<br>
To unsubscribe from this topic, visit <a href="https://groups.google.com/d/topic/haskell-cafe/9X2J65gXGXs/unsubscribe" target="_blank">https://groups.google.com/d/topic/haskell-cafe/9X2J65gXGXs/unsubscribe</a>.<br>
To unsubscribe from this group and all its topics, send an email to <a href="mailto:haskell-cafe%2Bunsubscribe@googlegroups.com">haskell-cafe+unsubscribe@googlegroups.com</a>.<br>
To post to this group, send email to <a href="mailto:haskell-cafe@googlegroups.com">haskell-cafe@googlegroups.com</a>.<br>
Visit this group at <a href="http://groups.google.com/group/haskell-cafe" target="_blank">http://groups.google.com/group/haskell-cafe</a>.<br>
For more options, visit <a href="https://groups.google.com/groups/opt_out" target="_blank">https://groups.google.com/groups/opt_out</a>.<br>
<br>
<br>
<br></blockquote></div><br></div>