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