Changeset 26278 in project


Ignore:
Timestamp:
03/29/12 18:25:01 (9 years ago)
Author:
certainty
Message:

nomads: documented the cli

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/eggref/4/nomads

    r24502 r26278  
    1212
    1313=== Examples
    14 <enscript highlight="scheme">
    15 (use nomads nomads-sql-de-lite fmt fmt-color filepath)
    16 
    17 (migration-directory "./migrations")
    18 (database-credentials "test.db")
    19 
    20 (define (get-version)
    21   (let ((version (get-environment-variable "VERSION")))
    22     (if version
    23         (or (string->number version) (string->symbol version))
    24         'latest)))
    25 
    26 
    27 (define (pretty-print-migration checkpoint irreversible?)
    28   (let ((direction (car checkpoint))
    29         (migration (cdr checkpoint)))
    30     (fmt #t
    31      (pad-char #\.
    32                (cat "["
    33                     (fmt-bold (migration-version migration))
    34                     "] "
    35                     (filepath:drop-extension (migration-filename migration))
    36                     " "
    37                     (space-to 72)
    38                     "["
    39                     (fmt-bold (if irreversible? (fmt-red "IRREVERSIBLE")  (fmt-green "OK")))
    40                     "]")))
    41     (newline)))
    42 
    43 
    44 (migrate version: (get-version) callback: pretty-print-migration)
    45 </enscript>
    46 
    47 You can compile and use this little program to control your migrations from the command-line along with pretty-printing what it does.
    48 
    49  $ csi -s migrate
    50  $ VERSION=2 csi -s migrate
    51 
    52 Where a migration file inside the {{migration-directory}} may look something like this.
    53 
    54  ;; 1-create-tests.scm
    55  ((UP
    56     "CREATE TABLE tests (name string)")
    57   (DOWN
    58    "DROP TABLE tests"))
     14Suppose you have project in which you want to manage your database migrations.
     15There is a directory "migrations" which will hold your migrations.
     16So your minimal directory structure looks like this:
     17
     18   /project
     19     |--- migrations
     20
     21You need to place a configuration-file '''nomads.config''' in the project's root
     22
     23   /project
     24     |--- nomdas.config
     25     |--- migrations
     26
     27This configuration-file may looks something like this.
     28
     29
     30   ((nomads
     31     (migration-directory "migrations")
     32     (database
     33       (adapter sqlite)
     34       (credentials "test.db"))))
     35
     36You set the path to the migrations, which is intepreted relative to where the config-file lies. Also you specify the database-adapter and credentials.
     37
     38Now you're read to manage your migrations.
     39
     40==== Generate a Migration
     41In your project's root do
     42
     43  $ nomads migrate my-first-migration
     44
     45This will generate a migration-file inside your migration-directory.
     46So your project-directory might look something like this now.
     47
     48   /project
     49      |---- nomads.config
     50      |---- migrations
     51               |---- 1333037112-my-first-migration
     52
     53Now edit this file with your migration code. For example with the following:
     54
     55   ((UP
     56      "CREATE TABLE tests (name string)")
     57    (DOWN
     58      "DROP TABLE tests"))
     59
     60==== Migrate Up
     61With the above migration you can now run it with:
     62
     63   $ nomads migrate
     64
     65This will run the migration and inform you about the result.
     66
     67==== Migrating Down
     68Now you can revert your changes by issueing:
     69
     70   $ nomads migrate -d
     71
     72This will migrate down.
     73
     74You can also migrate to a specific version. See the CLI-Documentation for that
     75
    5976
    6077
     
    6279[[/users/david-krentzlin|David Krentzlin]]
    6380
     81=== CLI-Documentation
     82Nomads comes with a tiny cli that can be used to manage your migrations.
     83It allows you to generate migrations as well as migrate up and down.
     84A simple '''nomads -h''' reveals the following:
     85
     86   Usage: nomads [options] command [options]
     87
     88   Options
     89   =======
     90    -c, --configfile=ARG     path to the configuration. Default ./nomads.config
     91    -h, --help               Display this help
     92
     93   Commands
     94   ========
     95    generate            Generate a new migration file
     96    migrate             Run the migrations
     97
     98As you can see, it supports git-style subcommands to do its work.
     99
     100==== The configuration
     101Before you can start using it, you need to tell it how to do its work. You do that by placing a configuration file in your project's root. The documentation will be read using [[simple-configuration]] with evaluation turned off.
     102A sample configuration for '''sqlite3''' may look like this:
     103
     104   ((nomads
     105     (migration-directory "migrations")
     106     (database
     107       (adapter sqlite)
     108       (credentials "test.db"))))
     109
     110A sample configuration for '''postgresql''' may look like this:
     111   ((nomads
     112     (migration-directory "migrations")
     113     (database
     114       (adapter postgresql)
     115       (credentials
     116          ((host . "127.0.0.1") (user . "testuser") (password . "testpassword") (dbname . "testdb"))))))
     117
     118* '''migration-directory''': This is the directory, releative to the project's root, where the migrations are located
     119* '''database''': This section configures the database.
     120* '''database/adapter''': The adapter to be used. Currently supported are '''sqlite''' and '''postgresql'''
     121* '''database/credentials''': The credentials needed for a connection to the database.
     122
     123==== Generation
     124You can issue '''nomads generate -h''' to see further options.
     125
     126    $ nomads generate migratione-name
     127
     128This will generate a migration in the configured migrations-directory using the timestamped versioning scheme.
     129
     130==== Migration
     131Once you have migrations in place you can use them:
     132
     133    $ nomads migrate -u
     134    $ nomads migrate -d
     135    $ nomads migrate -v specific-version
     136
     137This will migrate up, down or to a specific version. The default action is to migrate up. So you don't have to specify the explicitly.
     138
     139===== Planned features:
     140
     141* rollback the last migration
     142* report the current migration status
     143
     144=== API-Documentation
     145
     146==== Supported Databases
     147The library does currently ship with support for  '''sqlite3''' through [[sql-de-lite]], and '''postgresql''' through  [[postgresql]].
     148You can enable the adapter by requiring the library-part accordingly.
     149
     150'''Enabling the postgresql-support'''
     151 (use nomads nomads-postgresql)
     152 (database-credentials '((host . "127.0.0.1") (user . "testuser") (password . "testpassword") (dbname . "testdb")))
     153
     154'''Enabling the sqlite-support'''
     155 (use nomads nomads-sql-de-lite)
     156 (database-credentials "/path/to/db")
     157
     158==== Migrationfiles
     159The migrationfiles must match the following layout
     160
     161 ((UP
     162     "statement1"
     163     "statement2"
     164     "statementx")
     165  (DOWN
     166    "statement1down"
     167    "statement2down"
     168    "statementxdown"))
     169
     170Depending on the direction, the library will either execute the statements in the DOWN or in the UP section of the file.
     171There are two special kinds of statements.
     172
     173===== Lambdas
     174Those can be used to implement migrations that can not be expressed by simple sql-statements
     175
     176 ((UP
     177    ,(lambda (connection) (do-something-difficult connection))
     178  (DOWN
     179   "statement1"))
     180   
     181
     182===== Irreversible Migrations
     183If a #f is encountered the migration is interpreted as '''irreversible'''. An irreversible migration can not be reverted. In such a case, the library stops
     184at this migration and does not attempt to revert earlier migrations.
     185
     186 ((UP
     187    "statement1")
     188  (DOWN #f))
     189
     190==== Configuration
     191There are some parameters that you might want to tweak to use migrations. There are also some parameters that allow you to tweak the behaviour of the library even more. See the {{versioning}} section for details.
     192Most of the time though you'll only have to set two parameters for the library to function.
     193
     194<parameter>database-credentials</parameter>
     195
     196Depending on the database-binding you use, this holds the connection-specification that will be passed to the binding's connect-procedure.
     197See the documentation for [[sql-de-lite]] and [[postgresql]] for details.
     198
     199<parameter>migration-directory</parameter>
     200
     201As the name suggests this parameter specifies where migration files can be found.
     202
     203<parameter>error-on-duplicate-migrations</parameter>
     204
     205If this parameter is set to {{#t}} (the default) a condition of kind (nomads-error duplicate-version) is signaled.
     206
     207<parameter>error-on-non-existent-migration</parameter>
     208
     209If this parameter is set to {{#t}} (the default) a condition of kind (nomads-error non-existent-version) is signaled.
     210
     211===== Versioning and filename format
     212The library allows you to implement your own custom versioning scheme. By default it uses a simple sequential scheme, that simple prefixes every migration with a numeric value. You're free to implement your own versioning scheme, for example to use timestamped versioning.
     213
     214<parameter>filename-pattern</parameter>
     215<parameter>filename-partitioner</parameter>
     216<parameter>filename-joiner</parameter>
     217<parameter>versioner</parameter>
     218<parameter>version?</parameter>
     219<parameter>version-less?</parameter>
     220<parameter>version-equal?</parameter>
     221<parameter>version->string</parameter>
     222<parameter>string->version</parameter>
     223
     224The following example set's up a versioning scheme that uses timestamps
     225
     226<enscript language="scheme">
     227(use nomads nomads-sql-de-lite numbers)
     228
     229(versioner (lambda (max-version)
     230            (inexact->exact (current-seconds))))
     231
     232(filename-partitioner     
     233 (lambda (filename)
     234   (let ((parts (string-split filename "-")))
     235     (cond
     236      ((null? parts) (cons #f ""))
     237      ((string->number (car parts))
     238       => (lambda (num)
     239            (cons (number->string (inexact->exact num)) (string-join (cdr parts) "-"))))
     240      (else (cons #f filename))))))
     241
     242(filename-joiner           
     243 (lambda (version file)
     244    (sprintf "~A-~A" version file)))
     245
     246 ;;we need to bind it to the number's version of those
     247(version? number?)
     248
     249(define (->number what)
     250  (inexact->exact (if (string? what) (string->number what) what)))
     251
     252(version-less?
     253 (lambda (l r)
     254   (< (->number l) (->number r))))
     255
     256(version-equal?
     257 (lambda (l r)
     258   (equal? (->number l) (->number r))))
     259</enscript>
     260==== Generating Migrations
     261
     262<procedure>(generate-migration name)</procedure>
     263
     264The procedure generates a migration-stub inside {{migration-directory}} with the given name.
     265It returns the full name of the migration-file including the version.
     266
     267
     268==== Running Migrations
     269<procedure>(migrate #!key (version 'latest) (callback default-callback))</procedure>
     270
     271This procedure starts the migration process. It migrates from the currently active version to {{version}}.
     272Depending on the active version the migrations run downwards or upwards executing the DOWN and UP portion of the files respectively.
     273After each check-point (a single migration) {{callback}} is invoked. If you do not specify this argument the {{default-handler}} will just print which migration have been executed and their status.
    64274
    65275
     
    84294  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    85295  OTHER DEALINGS IN THE SOFTWARE.
    86 
    87 === Documentation
    88 
    89 ==== Supported Databases
    90 The library does currently ship with support for  '''sqlite3''' through [[sql-de-lite]], and '''postgresql''' through  [[postgresql]].
    91 You can enable the adapter by requiring the library-part accordingly.
    92 
    93 '''Enabling the postgresql-support'''
    94  (use nomads nomads-postgresql)
    95  (database-credentials '((host . "127.0.0.1") (user . "testuser") (password . "testpassword") (dbname . "testdb")))
    96 
    97 '''Enabling the sqlite-support'''
    98  (use nomads nomads-sql-de-lite)
    99  (database-credentials "/path/to/db")
    100 
    101 ==== Migrationfiles
    102 The migrationfiles must match the following layout
    103 
    104  ((UP
    105      "statement1"
    106      "statement2"
    107      "statementx")
    108   (DOWN
    109     "statement1down"
    110     "statement2down"
    111     "statementxdown"))
    112 
    113 Depending on the direction, the library will either execute the statements in the DOWN or in the UP section of the file.
    114 There are two special kinds of statements.
    115 
    116 ===== Lambdas
    117 Those can be used to implement migrations that can not be expressed by simple sql-statements
    118 
    119  ((UP
    120     ,(lambda (connection) (do-something-difficult connection))
    121   (DOWN
    122    "statement1"))
    123    
    124 
    125 ===== Irreversible Migrations
    126 If a #f is encountered the migration is interpreted as '''irreversible'''. An irreversible migration can not be reverted. In such a case, the library stops
    127 at this migration and does not attempt to revert earlier migrations.
    128 
    129  ((UP
    130     "statement1")
    131   (DOWN #f))
    132 
    133 ==== Configuration
    134 There are some parameters that you might want to tweak to use migrations. There are also some parameters that allow you to tweak the behaviour of the library even more. See the {{versioning}} section for details.
    135 Most of the time though you'll only have to set two parameters for the library to function.
    136 
    137 <parameter>database-credentials</parameter>
    138 
    139 Depending on the database-binding you use, this holds the connection-specification that will be passed to the binding's connect-procedure.
    140 See the documentation for [[sql-de-lite]] and [[postgresql]] for details.
    141 
    142 <parameter>migration-directory</parameter>
    143 
    144 As the name suggests this parameter specifies where migration files can be found.
    145 
    146 <parameter>error-on-duplicate-migrations</parameter>
    147 
    148 If this parameter is set to {{#t}} (the default) a condition of kind (nomads-error duplicate-version) is signaled.
    149 
    150 <parameter>error-on-non-existent-migration</parameter>
    151 
    152 If this parameter is set to {{#t}} (the default) a condition of kind (nomads-error non-existent-version) is signaled.
    153 
    154 ===== Versioning and filename format
    155 The library allows you to implement your own custom versioning scheme. By default it uses a simple sequential scheme, that simple prefixes every migration with a numeric value. You're free to implement your own versioning scheme, for example to use timestamped versioning.
    156 
    157 <parameter>filename-pattern</parameter>
    158 <parameter>filename-partitioner</parameter>
    159 <parameter>filename-joiner</parameter>
    160 <parameter>versioner</parameter>
    161 <parameter>version?</parameter>
    162 <parameter>version-less?</parameter>
    163 <parameter>version-equal?</parameter>
    164 <parameter>version->string</parameter>
    165 <parameter>string->version</parameter>
    166 
    167 The following example set's up a versioning scheme that uses timestamps
    168 
    169 <enscript language="scheme">
    170 (use nomads nomads-sql-de-lite numbers)
    171 
    172 (versioner (lambda (max-version)
    173             (inexact->exact (current-seconds))))
    174 
    175 (filename-partitioner     
    176  (lambda (filename)
    177    (let ((parts (string-split filename "-")))
    178      (cond
    179       ((null? parts) (cons #f ""))
    180       ((string->number (car parts))
    181        => (lambda (num)
    182             (cons (number->string (inexact->exact num)) (string-join (cdr parts) "-"))))
    183       (else (cons #f filename))))))
    184 
    185 (filename-joiner           
    186  (lambda (version file)
    187     (sprintf "~A-~A" version file)))
    188 
    189  ;;we need to bind it to the number's version of those
    190 (version? number?)
    191 
    192 (define (->number what)
    193   (inexact->exact (if (string? what) (string->number what) what)))
    194 
    195 (version-less?
    196  (lambda (l r)
    197    (< (->number l) (->number r))))
    198 
    199 (version-equal?
    200  (lambda (l r)
    201    (equal? (->number l) (->number r))))
    202 </enscript>
    203 ==== Generating Migrations
    204 
    205 <procedure>(generate-migration name)</procedure>
    206 
    207 The procedure generates a migration-stub inside {{migration-directory}} with the given name.
    208 It returns the full name of the migration-file including the version.
    209 
    210 
    211 ==== Running Migrations
    212 <procedure>(migrate #!key (version 'latest) (callback default-callback))</procedure>
    213 
    214 This procedure starts the migration process. It migrates from the currently active version to {{version}}.
    215 Depending on the active version the migrations run downwards or upwards executing the DOWN and UP portion of the files respectively.
    216 After each check-point (a single migration) {{callback}} is invoked. If you do not specify this argument the {{default-handler}} will just print which migration have been executed and their status.
Note: See TracChangeset for help on using the changeset viewer.