knex/docs/lib/migrate.html

224 lines
49 KiB
HTML
Raw Normal View History

2013-11-25 02:06:42 -05:00
<!DOCTYPE html><html lang="en"><head><title>lib/migrate</title></head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"><meta name="groc-relative-root" content="../"><meta name="groc-document-path" content="lib/migrate"><meta name="groc-project-path" content="lib/migrate.js"><link rel="stylesheet" type="text/css" media="all" href="../assets/style.css"><script type="text/javascript" src="../assets/behavior.js"></script><body><div id="meta"><div class="file-path">lib/migrate.js</div></div><div id="document"><div class="segment"><div class="comments"><div class="wrapper"><h2 id="migrate">Migrate</h2></div></div></div><div class="segment"><div class="code"><div class="wrapper"><span class="s2">&quot;use strict&quot;</span><span class="p">;</span>
2013-09-13 13:50:41 -04:00
2013-11-25 02:06:42 -05:00
<span class="kd">var</span> <span class="nx">fs</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;fs&#39;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">path</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;path&#39;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">_</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;lodash&#39;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">mkdirp</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;mkdirp&#39;</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">Promise</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./promise&#39;</span><span class="p">).</span><span class="nx">Promise</span><span class="p">;</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>The new migration we're performing, typically called from the <code>knex.migrate</code>
interface on the main <code>knex</code> object. Passes the <code>knex</code> instance performing
the migration.</p></div></div><div class="code"><div class="wrapper"><span class="kd">var</span> <span class="nx">Migrate</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">instance</span><span class="p">)</span> <span class="p">{</span>
2013-09-13 13:50:41 -04:00
<span class="k">this</span><span class="p">.</span><span class="nx">knex</span> <span class="o">=</span> <span class="nx">instance</span><span class="p">;</span>
<span class="p">};</span>
2013-11-25 02:06:42 -05:00
<span class="nx">Migrate</span><span class="p">.</span><span class="nx">prototype</span> <span class="o">=</span> <span class="p">{</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Initializes the migration, taking an optional <code>config</code> object,
for things like the <code>tableName</code>.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">_init</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">config</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">defaults</span><span class="p">(</span><span class="nx">config</span> <span class="o">||</span> <span class="p">{},</span> <span class="p">{</span>
<span class="nx">extension</span><span class="o">:</span> <span class="s1">&#39;js&#39;</span><span class="p">,</span>
<span class="nx">tableName</span><span class="o">:</span> <span class="s1">&#39;knex_migrations&#39;</span><span class="p">,</span>
<span class="nx">directory</span><span class="o">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">()</span> <span class="o">+</span> <span class="s1">&#39;/migrations&#39;</span>
<span class="p">});</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">directory</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">&#39;./&#39;</span><span class="p">)</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">directory</span> <span class="o">=</span> <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">cwd</span><span class="p">(),</span> <span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">directory</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">this</span><span class="p">.</span><span class="nx">_init</span> <span class="o">=</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">([</span>
<span class="k">this</span><span class="p">.</span><span class="nx">ensureFolder</span><span class="p">(</span><span class="nx">config</span><span class="p">),</span>
<span class="k">this</span><span class="p">.</span><span class="nx">ensureTable</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span>
<span class="p">]).</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">_init</span><span class="p">;</span>
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Ensures that the proper table has been created,
dependent on the migration config settings.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">ensureTable</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">migration</span> <span class="o">=</span> <span class="k">this</span><span class="p">;</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">knex</span><span class="p">.</span><span class="nx">schema</span><span class="p">.</span><span class="nx">hasTable</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">tableName</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">exists</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">exists</span><span class="p">)</span> <span class="k">return</span> <span class="nx">migration</span><span class="p">.</span><span class="nx">createMigrationTable</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">tableName</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Ensures a folder for the migrations exist, dependent on the
migration config settings.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">ensureFolder</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">promisify</span><span class="p">(</span><span class="nx">fs</span><span class="p">.</span><span class="nx">stat</span><span class="p">,</span> <span class="nx">fs</span><span class="p">)(</span><span class="nx">config</span><span class="p">.</span><span class="nx">directory</span><span class="p">)</span>
<span class="p">.</span><span class="k">catch</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">promisify</span><span class="p">(</span><span class="nx">mkdirp</span><span class="p">)(</span><span class="nx">config</span><span class="p">.</span><span class="nx">directory</span><span class="p">);</span>
<span class="p">});</span>
2013-09-13 13:50:41 -04:00
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Create the migration table, if it doesn't already exist.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">createMigrationTable</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tableName</span><span class="p">)</span> <span class="p">{</span>
2013-11-25 02:06:42 -05:00
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">knex</span><span class="p">.</span><span class="nx">schema</span><span class="p">.</span><span class="nx">createTable</span><span class="p">(</span><span class="nx">tableName</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">t</span><span class="p">)</span> <span class="p">{</span>
2013-09-13 13:50:41 -04:00
<span class="nx">t</span><span class="p">.</span><span class="nx">increments</span><span class="p">();</span>
<span class="nx">t</span><span class="p">.</span><span class="nx">string</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">);</span>
<span class="nx">t</span><span class="p">.</span><span class="nx">integer</span><span class="p">(</span><span class="s1">&#39;batch&#39;</span><span class="p">);</span>
<span class="nx">t</span><span class="p">.</span><span class="nx">dateTime</span><span class="p">(</span><span class="s1">&#39;migration_time&#39;</span><span class="p">);</span>
<span class="p">});</span>
2013-11-25 02:06:42 -05:00
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Migrates to the latest configuration.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">latest</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">init</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">migrationData</span><span class="p">)</span>
<span class="p">.</span><span class="nx">tap</span><span class="p">(</span><span class="nx">validateMigrationList</span><span class="p">)</span>
2013-09-13 13:50:41 -04:00
<span class="p">.</span><span class="nx">spread</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">all</span><span class="p">,</span> <span class="nx">completed</span><span class="p">)</span> <span class="p">{</span>
2013-11-25 02:06:42 -05:00
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">runBatch</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">difference</span><span class="p">(</span><span class="nx">all</span><span class="p">,</span> <span class="nx">completed</span><span class="p">),</span> <span class="s1">&#39;up&#39;</span><span class="p">);</span>
2013-09-13 13:50:41 -04:00
<span class="p">})</span>
2013-11-25 02:06:42 -05:00
<span class="p">.</span><span class="nx">bind</span><span class="p">();</span>
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Rollback the last "batch" of migrations that were run.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">rollback</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">init</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">migrationData</span><span class="p">)</span>
<span class="p">.</span><span class="nx">tap</span><span class="p">(</span><span class="nx">validateMigrationList</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">getLastBatch</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">migrations</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">runBatch</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">pluck</span><span class="p">(</span><span class="nx">migrations</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span><span class="p">),</span> <span class="s1">&#39;down&#39;</span><span class="p">);</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">bind</span><span class="p">();</span>
2013-09-13 13:50:41 -04:00
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Run a batch of current migrations, in sequence.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">runBatch</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">migrations</span><span class="p">,</span> <span class="nx">direction</span><span class="p">)</span> <span class="p">{</span>
2013-11-25 02:06:42 -05:00
<span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">migrations</span><span class="p">,</span> <span class="nx">validateMigrationStructure</span><span class="p">(</span><span class="k">this</span><span class="p">))</span>
<span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">migrations</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">latestBatchNumber</span><span class="p">().</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">batchNo</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">direction</span> <span class="o">===</span> <span class="s1">&#39;up&#39;</span><span class="p">)</span> <span class="nx">batchNo</span><span class="o">++</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">batchNo</span><span class="p">;</span>
<span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">waterfallBatch</span><span class="p">(</span><span class="nx">migrations</span><span class="p">,</span> <span class="nx">direction</span><span class="p">));</span>
2013-09-13 13:50:41 -04:00
<span class="p">});</span>
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Retrieves and returns the current migration version
we're on, as a promise. If there aren't any migrations run yet,
return "none" as the value for the <code>currentVersion</code>.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">currentVersion</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">listCompleted</span><span class="p">(</span><span class="nx">config</span><span class="p">).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">completed</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">val</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">chain</span><span class="p">(</span><span class="nx">completed</span><span class="p">).</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">value</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;_&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
<span class="p">}).</span><span class="nx">max</span><span class="p">().</span><span class="nx">value</span><span class="p">();</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">val</span> <span class="o">===</span> <span class="o">-</span><span class="kc">Infinity</span> <span class="o">?</span> <span class="s1">&#39;none&#39;</span> <span class="o">:</span> <span class="nx">val</span><span class="p">);</span>
<span class="p">});</span>
2013-11-25 02:06:42 -05:00
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Creates a new migration, with a given name.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">make</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">name</span><span class="p">)</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">rejected</span><span class="p">(</span><span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;A name must be specified for the generated migration&#39;</span><span class="p">));</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">init</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">generateStubTemplate</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">writeNewMigration</span><span class="p">(</span><span class="nx">name</span><span class="p">));</span>
2013-12-12 17:37:44 -05:00
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Lists all available migration versions, as a sorted array.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">listAll</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
2013-11-25 02:06:42 -05:00
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">init</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">promisify</span><span class="p">(</span><span class="nx">fs</span><span class="p">.</span><span class="nx">readdir</span><span class="p">,</span> <span class="nx">fs</span><span class="p">)(</span><span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">directory</span><span class="p">);</span>
2013-09-13 13:50:41 -04:00
<span class="p">})</span>
2013-12-12 17:37:44 -05:00
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">migrations</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">ext</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">extension</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">migrations</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">value</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">ext</span><span class="p">,</span> <span class="nx">value</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="nx">ext</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">!==</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}).</span><span class="nx">sort</span><span class="p">();</span>
<span class="p">});</span>
2013-09-13 13:50:41 -04:00
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Lists all migrations that have been completed for the current db, as an array.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">listCompleted</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
2013-11-25 02:06:42 -05:00
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">init</span><span class="p">(</span><span class="nx">config</span><span class="p">)</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">knex</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">tableName</span><span class="p">).</span><span class="nx">orderBy</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">).</span><span class="nx">select</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">);</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">migrations</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">pluck</span><span class="p">(</span><span class="nx">migrations</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span><span class="p">);</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">bind</span><span class="p">();</span>
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Gets the migration list from the specified migration directory,
as well as the list of completed migrations to check what
should be run.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">migrationData</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">all</span><span class="p">([</span>
<span class="k">this</span><span class="p">.</span><span class="nx">listAll</span><span class="p">(),</span>
<span class="k">this</span><span class="p">.</span><span class="nx">listCompleted</span><span class="p">()</span>
<span class="p">]);</span>
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Generates the stub template for the current migration, returning a compiled template.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">generateStubTemplate</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">stubPath</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">stub</span> <span class="o">||</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s1">&#39;stub&#39;</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">extension</span> <span class="o">+</span> <span class="s1">&#39;.stub&#39;</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">promisify</span><span class="p">(</span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span><span class="p">,</span> <span class="nx">fs</span><span class="p">)(</span><span class="nx">stubPath</span><span class="p">).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">stub</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span><span class="nx">stub</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="kc">null</span><span class="p">,</span> <span class="p">{</span><span class="nx">variable</span><span class="o">:</span> <span class="s1">&#39;d&#39;</span><span class="p">});</span>
<span class="p">});</span>
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Write a new migration to disk, using the config and generated filename,
passing any <code>variables</code> given in the config to the template.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">writeNewMigration</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">config</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">;</span>
<span class="k">return</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tmpl</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">===</span> <span class="s1">&#39;-&#39;</span><span class="p">)</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">filename</span> <span class="o">=</span> <span class="nx">yyyymmddhhmmss</span><span class="p">()</span> <span class="o">+</span> <span class="s1">&#39;_&#39;</span> <span class="o">+</span> <span class="nx">name</span> <span class="o">+</span> <span class="s1">&#39;.&#39;</span> <span class="o">+</span> <span class="nx">config</span><span class="p">.</span><span class="nx">extension</span><span class="p">;</span>
<span class="k">return</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">promisify</span><span class="p">(</span><span class="nx">fs</span><span class="p">.</span><span class="nx">writeFile</span><span class="p">,</span> <span class="nx">fs</span><span class="p">)(</span>
<span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">directory</span><span class="p">,</span> <span class="nx">filename</span><span class="p">),</span>
<span class="nx">tmpl</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">variables</span> <span class="o">||</span> <span class="p">{})</span>
<span class="p">).</span><span class="nx">yield</span><span class="p">(</span><span class="nx">filename</span><span class="p">);</span>
<span class="p">};</span>
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Get the last batch of migrations, by name, ordered by insert id
in reverse order.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">getLastBatch</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">knex</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">knex</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">tableName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">tableName</span><span class="p">;</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">knex</span><span class="p">(</span><span class="nx">tableName</span><span class="p">)</span>
<span class="p">.</span><span class="nx">where</span><span class="p">(</span><span class="s1">&#39;batch&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">select</span><span class="p">(</span><span class="nx">knex</span><span class="p">.</span><span class="nx">raw</span><span class="p">(</span><span class="s1">&#39;MAX(batch)&#39;</span><span class="p">)).</span><span class="nx">from</span><span class="p">(</span><span class="nx">tableName</span><span class="p">);</span>
<span class="p">})</span>
<span class="p">.</span><span class="nx">orderBy</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">,</span> <span class="s1">&#39;desc&#39;</span><span class="p">);</span>
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Returns the latest batch number.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">latestBatchNumber</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">knex</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">tableName</span><span class="p">)</span>
<span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="s1">&#39;batch as batchNo&#39;</span><span class="p">).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">obj</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">batchNo</span> <span class="o">||</span> <span class="mi">0</span><span class="p">);</span>
2013-09-13 13:50:41 -04:00
<span class="p">});</span>
2013-11-25 02:06:42 -05:00
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Runs a batch of <code>migrations</code> in a specified <code>direction</code>,
saving the appropriate database information as the migrations are run.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">waterfallBatch</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">migrations</span><span class="p">,</span> <span class="nx">direction</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">knex</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">knex</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">tableName</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">tableName</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">current</span> <span class="o">=</span> <span class="nx">Promise</span><span class="p">.</span><span class="nx">fulfilled</span><span class="p">().</span><span class="nx">bind</span><span class="p">({</span><span class="nx">failed</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">failedOn</span><span class="o">:</span> <span class="mi">0</span><span class="p">});</span>
<span class="kd">var</span> <span class="nx">log</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">return</span> <span class="kd">function</span><span class="p">(</span><span class="nx">batchNo</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">migrations</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">migration</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">name</span> <span class="o">=</span> <span class="nx">migration</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="nx">migration</span> <span class="o">=</span> <span class="nx">migration</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>We're going to run each of the migrations in the current "up"</p></div></div><div class="code"><div class="wrapper"> <span class="nx">current</span> <span class="o">=</span> <span class="nx">current</span><span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
2013-12-12 17:37:44 -05:00
<span class="k">return</span> <span class="nx">migration</span><span class="p">[</span><span class="nx">direction</span><span class="p">](</span><span class="nx">knex</span><span class="p">,</span> <span class="nx">Promise</span><span class="p">);</span>
2013-11-25 02:06:42 -05:00
<span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">name</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">direction</span> <span class="o">===</span> <span class="s1">&#39;up&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">knex</span><span class="p">(</span><span class="nx">tableName</span><span class="p">).</span><span class="nx">insert</span><span class="p">({</span>
<span class="nx">name</span><span class="o">:</span> <span class="nx">name</span><span class="p">,</span>
<span class="nx">batch</span><span class="o">:</span> <span class="nx">batchNo</span><span class="p">,</span>
<span class="nx">migration_time</span><span class="o">:</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">()</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">direction</span> <span class="o">===</span> <span class="s1">&#39;down&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">knex</span><span class="p">(</span><span class="nx">tableName</span><span class="p">).</span><span class="nx">where</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="nx">name</span><span class="p">}).</span><span class="nx">del</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">current</span><span class="p">.</span><span class="nx">yield</span><span class="p">([</span><span class="nx">batchNo</span><span class="p">,</span> <span class="nx">log</span><span class="p">]);</span>
2013-09-13 13:50:41 -04:00
<span class="p">};</span>
2013-11-25 02:06:42 -05:00
<span class="p">}</span>
2013-09-13 13:50:41 -04:00
2013-11-25 02:06:42 -05:00
<span class="p">};</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Validates some migrations by requiring and checking for an <code>up</code> and <code>down</code> function,
returning an array with the <code>item</code> and <code>migration</code> require.</p></div></div><div class="code"><div class="wrapper"><span class="kd">function</span> <span class="nx">validateMigrationStructure</span><span class="p">(</span><span class="nx">migrator</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">migration</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="nx">migrator</span><span class="p">.</span><span class="nx">config</span><span class="p">.</span><span class="nx">directory</span> <span class="o">+</span> <span class="s1">&#39;/&#39;</span> <span class="o">+</span> <span class="nx">item</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">migration</span><span class="p">.</span><span class="nx">up</span><span class="p">)</span> <span class="o">||</span> <span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">migration</span><span class="p">.</span><span class="nx">down</span><span class="p">))</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;Invalid migration: &#39;</span> <span class="o">+</span> <span class="nx">item</span> <span class="o">+</span> <span class="s1">&#39; must have both an up and down function&#39;</span><span class="p">);</span>
2013-09-13 13:50:41 -04:00
<span class="p">}</span>
2013-11-25 02:06:42 -05:00
<span class="k">return</span> <span class="p">[</span><span class="nx">item</span><span class="p">,</span> <span class="nx">migration</span><span class="p">];</span>
<span class="p">};</span>
<span class="p">}</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Validates that migrations are present in the appropriate directories.</p></div></div><div class="code"><div class="wrapper"><span class="kd">function</span> <span class="nx">validateMigrationList</span><span class="p">(</span><span class="nx">all</span><span class="p">,</span> <span class="nx">completed</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">diff</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">difference</span><span class="p">(</span><span class="nx">completed</span><span class="p">,</span> <span class="nx">all</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">isEmpty</span><span class="p">(</span><span class="nx">diff</span><span class="p">))</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span>
<span class="s1">&#39;The migration directory is corrupt, the following files are missing: &#39;</span> <span class="o">+</span> <span class="nx">diff</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;, &#39;</span><span class="p">)</span>
<span class="p">);</span>
2013-09-13 13:50:41 -04:00
<span class="p">}</span>
2013-11-25 02:06:42 -05:00
<span class="p">}</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Gets the current migration.</p></div></div><div class="code"><div class="wrapper"><span class="kd">var</span> <span class="nx">getMigration</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">all</span><span class="p">,</span> <span class="nx">version</span><span class="p">,</span> <span class="nx">config</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">found</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">all</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">item</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">version</span><span class="p">)</span> <span class="o">===</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">});</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">found</span><span class="p">)</span> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;Unable to locate the specified migration &#39;</span> <span class="o">+</span> <span class="nx">version</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">config</span><span class="p">.</span><span class="nx">directory</span><span class="p">,</span> <span class="nx">found</span><span class="p">);</span>
<span class="p">};</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Parse the version, which really only needs to be the
timestamp of the migration we wish to migrate to.</p></div></div><div class="code"><div class="wrapper"><span class="kd">var</span> <span class="nx">parseVersion</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">version</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">version</span> <span class="o">!==</span> <span class="s1">&#39;latest&#39;</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">version</span> <span class="o">=</span> <span class="nx">version</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">14</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">version</span><span class="p">.</span><span class="nx">length</span> <span class="o">!==</span> <span class="mi">14</span><span class="p">)</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;Invalid migration provided&#39;</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">version</span><span class="p">;</span>
<span class="p">};</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Get a date object in the correct format, without requiring
a full out library like "moment.js".</p></div></div><div class="code"><div class="wrapper"><span class="kd">var</span> <span class="nx">yyyymmddhhmmss</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
2013-09-13 13:50:41 -04:00
<span class="kd">var</span> <span class="nx">d</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
2013-11-25 02:06:42 -05:00
<span class="k">return</span> <span class="nx">d</span><span class="p">.</span><span class="nx">getFullYear</span><span class="p">().</span><span class="nx">toString</span><span class="p">()</span> <span class="o">+</span>
<span class="nx">padDate</span><span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="nx">getMonth</span><span class="p">()</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span>
<span class="nx">padDate</span><span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="nx">getDate</span><span class="p">())</span> <span class="o">+</span>
<span class="nx">padDate</span><span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="nx">getHours</span><span class="p">())</span> <span class="o">+</span>
<span class="nx">padDate</span><span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="nx">getMinutes</span><span class="p">())</span> <span class="o">+</span>
<span class="nx">padDate</span><span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="nx">getSeconds</span><span class="p">());</span>
2013-09-13 13:50:41 -04:00
<span class="p">};</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Ensure that we have 2 places for each of the date segments</p></div></div><div class="code"><div class="wrapper"><span class="kd">var</span> <span class="nx">padDate</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">segment</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">segment</span> <span class="o">=</span> <span class="nx">segment</span><span class="p">.</span><span class="nx">toString</span><span class="p">();</span>
<span class="k">return</span> <span class="nx">segment</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">?</span> <span class="nx">segment</span> <span class="o">:</span> <span class="s1">&#39;0&#39;</span> <span class="o">+</span> <span class="nx">segment</span><span class="p">;</span>
2013-11-25 02:06:42 -05:00
<span class="p">};</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Dasherize the string.</p></div></div><div class="code"><div class="wrapper"><span class="kd">var</span> <span class="nx">dasherize</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">str</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/([A-Z])/g</span><span class="p">,</span> <span class="s1">&#39;-$1&#39;</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/[-_\s]+/g</span><span class="p">,</span> <span class="s1">&#39;-&#39;</span><span class="p">).</span><span class="nx">toLowerCase</span><span class="p">();</span>
2013-09-13 13:50:41 -04:00
<span class="p">};</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="nx">Migrate</span><span class="p">;</span></div></div></div></div></body></html>