3
3
namespace Spatie \DbSnapshots ;
4
4
5
5
use Carbon \Carbon ;
6
+ use Illuminate \Contracts \Filesystem \Factory ;
6
7
use Illuminate \Filesystem \FilesystemAdapter as Disk ;
7
8
use Illuminate \Support \Facades \DB ;
8
9
use Illuminate \Support \LazyCollection ;
9
10
use Spatie \DbSnapshots \Events \DeletedSnapshot ;
10
11
use Spatie \DbSnapshots \Events \DeletingSnapshot ;
11
12
use Spatie \DbSnapshots \Events \LoadedSnapshot ;
12
13
use Spatie \DbSnapshots \Events \LoadingSnapshot ;
14
+ use Spatie \TemporaryDirectory \TemporaryDirectory ;
13
15
14
16
class Snapshot
15
17
{
@@ -25,6 +27,8 @@ class Snapshot
25
27
26
28
public const STREAM_BUFFER_SIZE = 16384 ;
27
29
30
+ protected Factory $ filesystemFactory ;
31
+
28
32
public function __construct (Disk $ disk , string $ fileName )
29
33
{
30
34
$ this ->disk = $ disk ;
@@ -39,6 +43,8 @@ public function __construct(Disk $disk, string $fileName)
39
43
}
40
44
41
45
$ this ->name = pathinfo ($ fileName , PATHINFO_FILENAME );
46
+
47
+ $ this ->filesystemFactory = app (Factory::class);
42
48
}
43
49
44
50
public function useStream ()
@@ -90,45 +96,65 @@ protected function shouldIgnoreLine(string $line): bool
90
96
91
97
protected function loadStream (string $ connectionName = null )
92
98
{
93
- LazyCollection::make (function () {
94
- $ stream = $ this ->compressionExtension === 'gz '
95
- ? gzopen ($ this ->disk ->path ($ this ->fileName ), 'r ' )
96
- : $ this ->disk ->readStream ($ this ->fileName );
97
-
98
- $ statement = '' ;
99
- while (! feof ($ stream )) {
100
- $ chunk = $ this ->compressionExtension === 'gz '
101
- ? gzread ($ stream , self ::STREAM_BUFFER_SIZE )
102
- : fread ($ stream , self ::STREAM_BUFFER_SIZE );
99
+ $ directory = (new TemporaryDirectory (config ('db-snapshots.temporary_directory_path ' )))->create ();
103
100
104
- $ lines = explode ("\n" , $ chunk );
105
- foreach ($ lines as $ idx => $ line ) {
106
- if ($ this ->shouldIgnoreLine ($ line )) {
107
- continue ;
108
- }
101
+ config ([
102
+ 'filesystems.disks. ' . self ::class => [
103
+ 'driver ' => 'local ' ,
104
+ 'root ' => $ directory ->path (),
105
+ 'throw ' => false ,
106
+ ]
107
+ ]);
109
108
110
- $ statement . = $ line ;
109
+ $ localDisk = $ this -> filesystemFactory -> disk ( self ::class) ;
111
110
112
- // Carry-over the last line to the next chunk since it
113
- // is possible that this chunk finished mid-line right on
114
- // a semi-colon.
115
- if (count ($ lines ) == $ idx + 1 ) {
116
- break ;
117
- }
111
+ try {
112
+ LazyCollection::make (function () use ($ localDisk ) {
113
+ $ localDisk ->writeStream ($ this ->fileName , $ this ->disk ->readStream ($ this ->fileName ));
114
+
115
+ $ stream = $ this ->compressionExtension === 'gz '
116
+ ? gzopen ($ localDisk ->path ($ this ->fileName ), 'r ' )
117
+ : $ localDisk ->readStream ($ this ->fileName );
118
118
119
- if (substr (trim ($ statement ), -1 , 1 ) === '; ' ) {
120
- yield $ statement ;
121
- $ statement = '' ;
119
+ $ statement = '' ;
120
+ while (! feof ($ stream )) {
121
+ $ chunk = $ this ->compressionExtension === 'gz '
122
+ ? gzread ($ stream , self ::STREAM_BUFFER_SIZE )
123
+ : fread ($ stream , self ::STREAM_BUFFER_SIZE );
124
+
125
+ $ lines = explode ("\n" , $ chunk );
126
+ foreach ($ lines as $ idx => $ line ) {
127
+ if ($ this ->shouldIgnoreLine ($ line )) {
128
+ continue ;
129
+ }
130
+
131
+ $ statement .= $ line ;
132
+
133
+ // Carry-over the last line to the next chunk since it
134
+ // is possible that this chunk finished mid-line right on
135
+ // a semi-colon.
136
+ if (count ($ lines ) == $ idx + 1 ) {
137
+ break ;
138
+ }
139
+
140
+ if (substr (trim ($ statement ), -1 , 1 ) === '; ' ) {
141
+ yield $ statement ;
142
+ $ statement = '' ;
143
+ }
122
144
}
123
145
}
124
- }
125
-
126
- if (substr (trim ($ statement ), -1 , 1 ) === '; ' ) {
127
- yield $ statement ;
128
- }
129
- })->each (function (string $ statement ) use ($ connectionName ) {
130
- DB ::connection ($ connectionName )->unprepared ($ statement );
131
- });
146
+
147
+ if ($ this ->compressionExtension === 'gz ' ) {
148
+ gzclose ($ stream );
149
+ } else {
150
+ fclose ($ stream );
151
+ }
152
+ })->each (function (string $ statement ) use ($ connectionName ) {
153
+ DB ::connection ($ connectionName )->unprepared ($ statement );
154
+ });
155
+ } finally {
156
+ $ directory ->delete ();
157
+ }
132
158
}
133
159
134
160
public function delete (): void
0 commit comments