Add description of Version set and start linking to it
[dbsrgits/DBIx-Class-DeploymentHandler.git] / lib / DBIx / Class / DeploymentHandler / HandlesVersioning.pm
1 package DBIx::Class::DeploymentHandler::HandlesVersioning;
2 use Moose::Role;
3
4 # note: the sets returned need to match!
5 requires 'next_version_set';
6 requires 'previous_version_set';
7
8 1;
9
10 # vim: ts=2 sw=2 expandtab
11
12 __END__
13
14 =head1 DESCRIPTION
15
16 Typically a VersionHandler will take a C<to_version> and yeild an iterator of
17 L<version sets|/VERSION SET>.
18
19 Typically a call to a VersionHandler's L</next_version_set> with a C<db_version>
20 of 1 and a C<to_version> of 5 will iterate over something like the following:
21
22  [1, 2]
23  [2, 3]
24  [3, 4]
25  [4, 5]
26  undef
27
28 or maybe just
29
30  [1, 5]
31  undef
32
33 Really how the L<version sets|/VERSION SET> are arranged is up to the
34 VersionHandler being used.
35
36 In some cases users will not want versions to have inherent "previous
37 versions," which is why the version set is an C<ArrayRef>.  In those cases the
38 user should opt to returning merely the version that the database is being
39 upgraded to in each step.
40
41 One idea that has been suggested to me has been to have a form of dependency
42 management of the database "versions."  In this case the versions are actually
43 more like features that may or may not be applied.  For example, one might
44 start with version 1 and have a feature (version) C<users>.
45
46 Each feature might require that the database be upgraded to another version
47 first.  If one were to implement a system like this, here is how the
48 VersionHandler's L</next_version_set> might look.
49
50  to_version = "users", db_version = 1
51  [3]
52  [5]
53  ["users"]
54  undef
55
56 So what just happened there is that C<users> depends on version 5, which depends
57 on version 3, which depends on version 1, which is already installed.  To be
58 clear, the reason we use single versions instead of version pairs is because
59 there is no inherent order for this type of database upgraded.
60
61 =head2 Downgrades
62
63 For the typical case downgrades should be easy for users to perform and
64 understand.  That means that with the first two examples given above we can use
65 the L</previous_version_set> iterator to yeild the following:
66
67
68  db_version = 5, to_version=1
69  [4, 5]
70  [3, 4]
71  [2, 3]
72  [1, 2]
73  undef
74
75 or maybe just
76
77  [1, 5]
78  undef
79
80 Note that we do not swap the version number order.  This allows us to remain
81 consistent in our version set abstraction, since a version set really just
82 describes a version change, and not necesarily a defined progression.
83
84 =method next_version_set
85
86  print 'versions to install: ';
87  while (my $vs = $dh->next_version_set) {
88    print join q(, ), @{$vs}
89  }
90  print qq(\n);
91
92 Return a L<version set|/VERSION SET> describing each version that needs to be
93 installed to upgrade to C<< $dh->to_version >>.
94
95 =method previous_version_set
96
97  print 'versions to uninstall: ';
98  while (my $vs = $dh->previous_version_set) {
99    print join q(, ), @{$vs}
100  }
101  print qq(\n);
102
103 Return a L<version set|/VERSION SET> describing each version that needs to be
104 "installed" to downgrade to C<< $dh->to_version >>.
105
106 =head1 VERSION SET
107
108 A version set could be defined as:
109
110  subtype 'Version', as 'Str';
111  subtype 'VersionSet', as 'ArrayRef[Str]';
112
113 A version set should uniquely identify a migration.
114
115 =head1 KNOWN IMPLEMENTATIONS
116
117 =over
118
119 =item *
120
121 L<DBIx::Class::DeploymentHandler::VersionHandler::Monotonic>
122
123 =item *
124
125 L<DBIx::Class::DeploymentHandler::VersionHandler::DatabaseToSchemaVersions>
126
127 =item *
128
129 L<DBIx::Class::DeploymentHandler::VersionHandler::ExplicitVersions>
130
131 =back
132