2222 */
2323class Seed
2424{
25+ /**
26+ * Taille des lots pour bulk insert
27+ */
28+ protected const DEFAULT_BULK_SIZE = 100 ;
29+
2530 /**
2631 * Builder pour la table
2732 */
@@ -51,6 +56,11 @@ class Seed
5156 */
5257 protected int $ rowCount = 30 ;
5358
59+ /**
60+ * Taille des lots pour bulk insert
61+ */
62+ protected int $ bulkSize = self ::DEFAULT_BULK_SIZE ;
63+
5464 /**
5565 * Faut-il vider la table avant ?
5666 */
@@ -129,6 +139,16 @@ public function rows(int $count): self
129139 return $ this ;
130140 }
131141
142+ /**
143+ * Définit la taille des lots pour bulk insert
144+ */
145+ public function bulkSize (int $ size ): self
146+ {
147+ $ this ->bulkSize = max (1 , $ size );
148+
149+ return $ this ;
150+ }
151+
132152 /**
133153 * Définit des données brutes
134154 */
@@ -161,6 +181,8 @@ public function truncate(bool $truncate = true): self
161181
162182 /**
163183 * Ajoute un callback avant chaque insertion
184+ *
185+ * @param Closure(array $data, int $index, ?int $insertId): array|null|void $callback
164186 */
165187 public function beforeInsert (callable $ callback ): self
166188 {
@@ -171,6 +193,8 @@ public function beforeInsert(callable $callback): self
171193
172194 /**
173195 * Ajoute un callback après chaque insertion
196+ *
197+ * @param Closure(array $data, int $index, ?int $insertId): array|null|void $callback
174198 */
175199 public function afterInsert (callable $ callback ): self
176200 {
@@ -188,10 +212,10 @@ public function execute(): void
188212 $ this ->builder ->truncate ();
189213 }
190214
191- if (! empty ( $ this ->rawData ) ) {
215+ if ($ this ->rawData !== [] ) {
192216 $ this ->insertRawData ();
193217 } else {
194- $ this ->generateData ();
218+ $ this ->generateAndInsertData ();
195219 }
196220 }
197221
@@ -202,50 +226,73 @@ protected function insertRawData(): void
202226 {
203227 $ columns = array_keys (reset ($ this ->rawData ));
204228
205- foreach ($ this ->rawData as $ index => $ row ) {
229+ $ chunks = array_chunk ($ this ->rawData , $ this ->bulkSize );
230+
231+ foreach ($ chunks as $ chunkIndex => $ chunk ) {
206232 $ data = [];
207- foreach ($ columns as $ column ) {
208- $ data [$ column ] = $ row [$ column ] ?? null ;
233+ foreach ($ chunk as $ rowIndex => $ row ) {
234+ $ preparedRow = [];
235+ foreach ($ columns as $ column ) {
236+ $ preparedRow [$ column ] = $ row [$ column ] ?? null ;
237+ }
238+
239+ $ this ->executeCallbacks ($ this ->beforeInsertCallbacks , $ preparedRow , $ rowIndex );
240+ $ data [] = $ preparedRow ;
241+ }
242+
243+ $ this ->builder ->bulkInsert ($ data );
244+
245+ // Callbacks after (avec l'ID du premier élément comme approximation)
246+ $ firstId = $ this ->db ->lastId ();
247+ foreach ($ data as $ index => $ row ) {
248+ $ this ->executeCallbacks ($ this ->afterInsertCallbacks , $ row , $ index , $ firstId + $ index );
209249 }
210-
211- $ this ->executeCallbacks ($ this ->beforeInsertCallbacks , $ data , $ index );
212- $ this ->builder ->insert ($ data );
213- $ this ->executeCallbacks ($ this ->afterInsertCallbacks , $ data , $ index , $ this ->db ->lastId ());
214250 }
215251 }
216252
217253 /**
218- * Génère les données
254+ * Génère et insère les données
219255 */
220- protected function generateData (): void
256+ protected function generateAndInsertData (): void
221257 {
222- // Résoudre les dépendances une seule fois
223- $ dependencies = $ this ->resolveDependencies ();
224-
225- // Générer les données ligne par ligne
226- for ($ i = 0 ; $ i < $ this ->rowCount ; $ i ++) {
227- $ row = [];
228-
229- // Traiter les configurations d'abord (plus rapides)
230- foreach ($ this ->columns as $ column => $ definition ) {
231- $ row [$ column ] = $ this ->resolveConfig ($ definition , $ dependencies );
232- }
233-
234- // Traiter les closures ensuite (plus flexibles)
235- foreach ($ this ->closures as $ column => $ closure ) {
236- $ row [$ column ] = $ closure ($ this ->faker , $ dependencies , $ i );
237- }
238-
239- $ this ->generated [] = $ row ;
240- }
241-
242- // Insérer les données
243- foreach ($ this ->generated as $ index => $ row ) {
244- $ this ->executeCallbacks ($ this ->beforeInsertCallbacks , $ row , $ index );
245- $ this ->builder ->insert ($ row );
246- $ this ->executeCallbacks ($ this ->afterInsertCallbacks , $ row , $ index , $ this ->db ->lastId ());
247- }
248- }
258+ // Résoudre les dépendances une seule fois
259+ $ dependencies = $ this ->resolveDependencies ();
260+
261+ // Générer les données par lots
262+ $ batches = (int ) ceil ($ this ->rowCount / $ this ->bulkSize );
263+
264+ for ($ batch = 0 ; $ batch < $ batches ; $ batch ++) {
265+ $ batchData = [];
266+ $ start = $ batch * $ this ->bulkSize ;
267+ $ end = min ($ start + $ this ->bulkSize , $ this ->rowCount );
268+
269+ for ($ i = $ start ; $ i < $ end ; $ i ++) {
270+ $ row = [];
271+
272+ // Traiter les configurations d'abord (plus rapides)
273+ foreach ($ this ->columns as $ column => $ definition ) {
274+ $ row [$ column ] = $ this ->resolveConfig ($ definition , $ dependencies );
275+ }
276+
277+ // Traiter les closures ensuite (plus flexibles)
278+ foreach ($ this ->closures as $ column => $ closure ) {
279+ $ row [$ column ] = $ closure ($ this ->faker , $ dependencies , $ i );
280+ }
281+
282+ $ this ->executeCallbacks ($ this ->beforeInsertCallbacks , $ row , $ i );
283+
284+ $ batchData [] = $ row ;
285+ }
286+
287+ $ this ->builder ->bulkInsert ($ batchData );
288+
289+ // Callbacks after (avec approximation des IDs)
290+ $ firstId = $ this ->db ->lastId ();
291+ foreach ($ batchData as $ offset => $ row ) {
292+ $ this ->executeCallbacks ($ this ->afterInsertCallbacks , $ row , $ start + $ offset , $ firstId + $ offset );
293+ }
294+ }
295+ }
249296
250297 /**
251298 * Résout une configuration
0 commit comments