1 package org.apache.continuum.dao;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.continuum.model.project.BuildResult;
23 import org.apache.maven.continuum.model.project.Project;
24 import org.apache.maven.continuum.project.ContinuumProjectState;
25 import org.apache.maven.continuum.store.ContinuumStoreException;
26 import org.springframework.stereotype.Repository;
27
28 import java.util.Calendar;
29 import java.util.Date;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33 import javax.jdo.Extent;
34 import javax.jdo.JDOHelper;
35 import javax.jdo.PersistenceManager;
36 import javax.jdo.Query;
37 import javax.jdo.Transaction;
38
39
40
41
42
43
44 @Repository( "buildResultDao" )
45 public class BuildResultDaoImpl
46 extends AbstractDao
47 implements BuildResultDao
48 {
49 public void updateBuildResult( BuildResult build )
50 throws ContinuumStoreException
51 {
52 PersistenceManager pm = getPersistenceManager();
53
54 Transaction tx = pm.currentTransaction();
55
56 Project project = build.getProject();
57 try
58 {
59 tx.begin();
60
61 if ( !JDOHelper.isDetached( build ) )
62 {
63 throw new ContinuumStoreException( "Not detached: " + build );
64 }
65
66 pm.makePersistent( build );
67
68 if ( !JDOHelper.isDetached( project ) )
69 {
70 throw new ContinuumStoreException( "Not detached: " + project );
71 }
72
73 project.setState( build.getState() );
74
75
76 pm.makePersistent( project );
77
78 tx.commit();
79 }
80 finally
81 {
82 rollback( tx );
83 }
84 }
85
86 public void addBuildResult( Project project, BuildResult build )
87 throws ContinuumStoreException
88 {
89 PersistenceManager pm = getPersistenceManager();
90
91 Transaction tx = pm.currentTransaction();
92
93 try
94 {
95 tx.begin();
96
97 pm.getFetchPlan().addGroup( PROJECT_WITH_BUILDS_FETCH_GROUP );
98
99 Object objectId = pm.newObjectIdInstance( Project.class, project.getId() );
100
101 project = (Project) pm.getObjectById( objectId );
102
103 build = (BuildResult) makePersistent( pm, build, false );
104
105
106
107 project.setLatestBuildId( build.getId() );
108
109 project.setState( build.getState() );
110
111 project.addBuildResult( build );
112
113 tx.commit();
114 }
115 finally
116 {
117 rollback( tx );
118 }
119 }
120
121 public BuildResult getLatestBuildResultForProject( int projectId )
122 {
123 PersistenceManager pm = getPersistenceManager();
124
125 Transaction tx = pm.currentTransaction();
126
127 try
128 {
129 tx.begin();
130
131 Extent extent = pm.getExtent( BuildResult.class, true );
132
133 Query query = pm.newQuery( extent );
134
135 query.declareParameters( "int projectId" );
136
137 query.setFilter( "this.project.id == projectId && this.project.latestBuildId == this.id" );
138
139 List<BuildResult> result = (List<BuildResult>) query.execute( projectId );
140
141 result = (List<BuildResult>) pm.detachCopyAll( result );
142
143 tx.commit();
144
145 if ( result != null && !result.isEmpty() )
146 {
147 return result.get( 0 );
148 }
149 }
150 finally
151 {
152 rollback( tx );
153 }
154 return null;
155 }
156
157 public BuildResult getLatestBuildResultForProjectWithDetails( int projectId )
158 {
159 PersistenceManager pm = getPersistenceManager();
160
161 Transaction tx = pm.currentTransaction();
162
163 try
164 {
165 tx.begin();
166
167 pm.getFetchPlan().addGroup( BUILD_RESULT_WITH_DETAILS_FETCH_GROUP );
168
169 Extent extent = pm.getExtent( BuildResult.class, true );
170
171 Query query = pm.newQuery( extent );
172
173 query.declareParameters( "int projectId" );
174
175 query.setFilter( "this.project.id == projectId && this.project.latestBuildId == this.id" );
176
177 List<BuildResult> result = (List<BuildResult>) query.execute( projectId );
178
179 result = (List<BuildResult>) pm.detachCopyAll( result );
180
181 tx.commit();
182
183 if ( result != null && !result.isEmpty() )
184 {
185 return result.get( 0 );
186 }
187 }
188 finally
189 {
190 rollback( tx );
191 }
192 return null;
193 }
194
195 public BuildResult getLatestBuildResultForBuildDefinition( int projectId, int buildDefinitionId )
196 {
197 PersistenceManager pm = getPersistenceManager();
198
199 Transaction tx = pm.currentTransaction();
200
201 try
202 {
203 tx.begin();
204
205 Extent extent = pm.getExtent( BuildResult.class, true );
206
207 Query query = pm.newQuery( extent );
208
209 query.declareParameters( "int projectId, int buildDefinitionId" );
210
211 query.setFilter( "this.project.id == projectId && this.buildDefinition.id == buildDefinitionId" );
212 query.setOrdering( "id descending" );
213
214 Object[] params = new Object[2];
215 params[0] = projectId;
216 params[1] = buildDefinitionId;
217
218 List<BuildResult> result = (List<BuildResult>) query.executeWithArray( params );
219
220 result = (List<BuildResult>) pm.detachCopyAll( result );
221
222 tx.commit();
223
224 if ( result != null && !result.isEmpty() )
225 {
226 return result.get( 0 );
227 }
228 }
229 finally
230 {
231 rollback( tx );
232 }
233 return null;
234 }
235
236 public Map<Integer, BuildResult> getLatestBuildResultsByProjectGroupId( int projectGroupId )
237 {
238 PersistenceManager pm = getPersistenceManager();
239
240 Transaction tx = pm.currentTransaction();
241
242 try
243 {
244 tx.begin();
245
246 Extent extent = pm.getExtent( BuildResult.class, true );
247
248 Query query = pm.newQuery( extent );
249
250 String filter = "this.project.latestBuildId == this.id";
251
252 if ( projectGroupId > 0 )
253 {
254 query.declareParameters( "int projectGroupId" );
255 filter += " && this.project.projectGroup.id == projectGroupId";
256 }
257
258 query.setFilter( filter );
259
260 List<BuildResult> result;
261 if ( projectGroupId > 0 )
262 {
263 result = (List<BuildResult>) query.execute( projectGroupId );
264 }
265 else
266 {
267 result = (List<BuildResult>) query.execute();
268 }
269
270 result = (List<BuildResult>) pm.detachCopyAll( result );
271
272 tx.commit();
273
274 if ( result != null && !result.isEmpty() )
275 {
276 Map<Integer, BuildResult> builds = new HashMap<Integer, BuildResult>();
277
278 for ( BuildResult br : result )
279 {
280 builds.put( br.getProject().getId(), br );
281 }
282
283 return builds;
284 }
285 }
286 finally
287 {
288 rollback( tx );
289 }
290
291 return null;
292 }
293
294 public void removeBuildResult( BuildResult buildResult )
295 {
296 removeObject( buildResult );
297 }
298
299 public List<BuildResult> getAllBuildsForAProjectByDate( int projectId )
300 {
301 PersistenceManager pm = getPersistenceManager();
302
303 Transaction tx = pm.currentTransaction();
304
305 try
306 {
307 tx.begin();
308
309 Query query = pm.newQuery( "SELECT FROM " + BuildResult.class.getName() +
310 " WHERE project.id == projectId PARAMETERS int projectId ORDER BY endTime DESC" );
311
312 query.declareImports( "import java.lang.Integer" );
313
314 query.declareParameters( "Integer projectId" );
315
316 List<BuildResult> result = (List<BuildResult>) query.execute( projectId );
317
318 result = (List<BuildResult>) pm.detachCopyAll( result );
319
320 tx.commit();
321
322 return result;
323 }
324 finally
325 {
326 rollback( tx );
327 }
328 }
329
330 public BuildResult getBuildResult( int buildId )
331 throws ContinuumStoreException
332 {
333 return (BuildResult) getObjectById( BuildResult.class, buildId, BUILD_RESULT_WITH_DETAILS_FETCH_GROUP );
334 }
335
336 public List<BuildResult> getBuildResultByBuildNumber( int projectId, int buildNumber )
337 {
338 PersistenceManager pm = getPersistenceManager();
339
340 Transaction tx = pm.currentTransaction();
341
342 try
343 {
344 tx.begin();
345
346 Extent extent = pm.getExtent( BuildResult.class, true );
347
348 Query query = pm.newQuery( extent );
349
350 query.declareParameters( "int projectId, int buildNumber" );
351
352 query.setFilter( "this.project.id == projectId && this.buildNumber == buildNumber" );
353
354 List<BuildResult> result = (List<BuildResult>) query.execute( projectId, buildNumber );
355
356 result = (List<BuildResult>) pm.detachCopyAll( result );
357
358 tx.commit();
359
360 return result;
361 }
362 finally
363 {
364 rollback( tx );
365 }
366 }
367
368 public List<BuildResult> getBuildResultsByBuildDefinition( int projectId, int buildDefinitionId )
369 {
370 return getBuildResultsByBuildDefinition( projectId, buildDefinitionId, -1, -1 );
371 }
372
373 public List<BuildResult> getBuildResultsByBuildDefinition( int projectId, int buildDefinitionId, long startIndex,
374 long endIndex )
375 {
376 PersistenceManager pm = getPersistenceManager();
377
378 Transaction tx = pm.currentTransaction();
379
380 try
381 {
382 tx.begin();
383
384 Extent extent = pm.getExtent( BuildResult.class, true );
385
386 Query query = pm.newQuery( extent );
387
388 if ( startIndex >= 0 && endIndex >= 0 )
389 {
390 query.setRange( startIndex, endIndex );
391 }
392
393 query.declareParameters( "int projectId, int buildDefinitionId" );
394
395 query.setFilter( "this.project.id == projectId && this.buildDefinition.id == buildDefinitionId" );
396
397 query.setOrdering( "this.id descending" );
398
399 List<BuildResult> result = (List<BuildResult>) query.execute( projectId, buildDefinitionId );
400
401 result = (List<BuildResult>) pm.detachCopyAll( result );
402
403 tx.commit();
404
405 return result;
406 }
407 finally
408 {
409 rollback( tx );
410 }
411 }
412
413 public long getNbBuildResultsForProject( int projectId )
414 {
415 PersistenceManager pm = getPersistenceManager();
416
417 Transaction tx = pm.currentTransaction();
418
419 try
420 {
421 tx.begin();
422
423 Query query = pm.newQuery( BuildResult.class, "project.id == projectId" );
424
425 query.declareParameters( "int projectId" );
426
427 query.setResult( "count(this)" );
428
429 long result = (Long) query.execute( projectId );
430
431 tx.commit();
432
433 return result;
434 }
435 finally
436 {
437 rollback( tx );
438 }
439 }
440
441 public long getNbBuildResultsInSuccessForProject( int projectId, long fromDate )
442 {
443 PersistenceManager pm = getPersistenceManager();
444
445 Transaction tx = pm.currentTransaction();
446
447 try
448 {
449 tx.begin();
450
451 Extent extent = pm.getExtent( BuildResult.class, true );
452
453 Query query = pm.newQuery( extent );
454
455 query.declareParameters( "int projectId, long fromDate, int state" );
456
457 query.setFilter( "this.project.id == projectId && this.startTime > fromDate && this.state == state" );
458
459 query.setResult( "count(this)" );
460
461 long result = (Long) query.execute( projectId, fromDate, ContinuumProjectState.OK );
462
463 tx.commit();
464
465 return result;
466 }
467 finally
468 {
469 rollback( tx );
470 }
471 }
472
473 public List<BuildResult> getBuildResultsForProjectWithDetails( int projectId, long fromDate, int tobuildResultId )
474 {
475 PersistenceManager pm = getPersistenceManager();
476
477 Transaction tx = pm.currentTransaction();
478
479 try
480 {
481 tx.begin();
482
483 Extent extent = pm.getExtent( BuildResult.class, true );
484 pm.getFetchPlan().addGroup( BUILD_RESULT_WITH_DETAILS_FETCH_GROUP );
485
486 Query query = pm.newQuery( extent );
487
488 String parameters = "int projectId, long fromDate";
489 String filter = "this.project.id == projectId && this.startTime > fromDate";
490
491 if ( tobuildResultId > 0 )
492 {
493 parameters += ", int buildResultId";
494 filter += " && this.id < buildResultId";
495 }
496 query.declareParameters( parameters );
497
498 query.setFilter( filter );
499
500 query.setOrdering( "this.id descending" );
501
502 List<BuildResult> result;
503
504 if ( tobuildResultId > 0 )
505 {
506 result = (List<BuildResult>) query.execute( projectId, fromDate, tobuildResultId );
507 }
508 else
509 {
510 result = (List<BuildResult>) query.execute( projectId, fromDate );
511 }
512
513 result = (List<BuildResult>) pm.detachCopyAll( result );
514
515 tx.commit();
516
517 return result;
518 }
519 finally
520 {
521 rollback( tx );
522 }
523 }
524
525 public List<BuildResult> getBuildResultsForProject( int projectId )
526 {
527 return getBuildResultsForProjectWithDetails( projectId, -1, -1 );
528 }
529
530 public List<BuildResult> getBuildResultsForProject( int projectId, long startIndex, long endIndex )
531 {
532 PersistenceManager pm = getPersistenceManager();
533
534 Transaction tx = pm.currentTransaction();
535
536 try
537 {
538 tx.begin();
539
540 Extent extent = pm.getExtent( BuildResult.class, true );
541
542 Query query = pm.newQuery( extent );
543
544 query.declareParameters( "int projectId" );
545
546 query.setFilter( "this.project.id == projectId" );
547
548 query.setOrdering( "this.startTime descending" );
549
550 if ( startIndex >= 0 )
551 {
552 query.setRange( startIndex, endIndex );
553 }
554
555 List<BuildResult> result = (List<BuildResult>) query.execute( projectId );
556
557 result = (List<BuildResult>) pm.detachCopyAll( result );
558
559 tx.commit();
560
561 return result;
562 }
563 finally
564 {
565 rollback( tx );
566 }
567 }
568
569 public List<BuildResult> getBuildResultsForProjectFromId( int projectId, long startId )
570 throws ContinuumStoreException
571 {
572 PersistenceManager pm = getPersistenceManager();
573
574 Transaction tx = pm.currentTransaction();
575
576 pm.getFetchPlan().addGroup( BUILD_RESULT_WITH_DETAILS_FETCH_GROUP );
577
578 try
579 {
580 tx.begin();
581
582 Extent extent = pm.getExtent( BuildResult.class, true );
583
584 Query query = pm.newQuery( extent );
585
586 query.declareParameters( "int projectId, int buildNumber" );
587
588 query.setFilter( "this.project.id == projectId && this.buildNumber >= buildNumber" );
589
590 query.setOrdering( "this.startTime descending" );
591
592 List<BuildResult> result = (List<BuildResult>) query.execute( projectId, startId );
593
594 result = (List<BuildResult>) pm.detachCopyAll( result );
595
596 tx.commit();
597
598 return result;
599 }
600 catch ( Exception e )
601 {
602 throw new ContinuumStoreException( e.getMessage(), e );
603 }
604 finally
605 {
606 rollback( tx );
607 }
608 }
609
610 public BuildResult getLatestBuildResultInSuccess( int projectId )
611 {
612 PersistenceManager pm = getPersistenceManager();
613
614 Transaction tx = pm.currentTransaction();
615
616 try
617 {
618 tx.begin();
619
620 Extent extent = pm.getExtent( BuildResult.class, true );
621
622 Query query = pm.newQuery( extent );
623
624 query.declareParameters( "int projectId" );
625
626 String filter = "this.project.buildNumber == this.buildNumber && this.project.id == projectId";
627
628 query.setFilter( filter );
629
630 query.setUnique( true );
631
632 BuildResult result = (BuildResult) query.execute( projectId );
633
634 result = (BuildResult) pm.detachCopy( result );
635
636 tx.commit();
637
638 return result;
639 }
640 finally
641 {
642 rollback( tx );
643 }
644 }
645
646 private int getPreviousBuildResultIdInSuccess( int projectId, int buildResultId )
647 {
648 PersistenceManager pm = getPersistenceManager();
649
650 Transaction tx = pm.currentTransaction();
651
652 try
653 {
654 tx.begin();
655
656 Extent extent = pm.getExtent( BuildResult.class, true );
657
658 Query query = pm.newQuery( extent );
659
660 query.declareParameters( "int projectId, int buildResultId" );
661
662 String filter = "this.id < buildResultId && this.state == " + ContinuumProjectState.OK +
663 " && this.project.id == projectId";
664
665 query.setFilter( filter );
666
667 query.setResult( "max(this.id)" );
668
669 int result = (Integer) query.execute( projectId, buildResultId );
670
671 tx.commit();
672
673 return result;
674 }
675 finally
676 {
677 rollback( tx );
678 }
679 }
680
681 public BuildResult getPreviousBuildResultInSuccess( int projectId, int buildResultId )
682 throws ContinuumStoreException
683 {
684 try
685 {
686 return getBuildResult( getPreviousBuildResultIdInSuccess( projectId, buildResultId ) );
687 }
688 catch ( NullPointerException e )
689 {
690 return null;
691 }
692 }
693
694 public Map<Integer, BuildResult> getBuildResultsInSuccessByProjectGroupId( int projectGroupId )
695 {
696 PersistenceManager pm = getPersistenceManager();
697
698 Transaction tx = pm.currentTransaction();
699
700 try
701 {
702 tx.begin();
703
704 Extent extent = pm.getExtent( BuildResult.class, true );
705
706 Query query = pm.newQuery( extent );
707
708 String filter = "this.project.buildNumber == this.buildNumber";
709
710 if ( projectGroupId > 0 )
711 {
712 query.declareParameters( "int projectGroupId" );
713 filter += " && this.project.projectGroup.id == projectGroupId";
714 }
715
716 query.setFilter( filter );
717
718 List<BuildResult> result;
719
720 if ( projectGroupId > 0 )
721 {
722 result = (List<BuildResult>) query.execute( projectGroupId );
723 }
724 else
725 {
726 result = (List<BuildResult>) query.execute();
727 }
728
729 result = (List<BuildResult>) pm.detachCopyAll( result );
730
731 tx.commit();
732
733 if ( result != null && !result.isEmpty() )
734 {
735 Map<Integer, BuildResult> builds = new HashMap<Integer, BuildResult>();
736
737 for ( BuildResult br : result )
738 {
739 builds.put( br.getProject().getId(), br );
740 }
741
742 return builds;
743 }
744 }
745 finally
746 {
747 rollback( tx );
748 }
749
750 return null;
751 }
752
753 @SuppressWarnings( "unchecked" )
754 public List<BuildResult> getBuildResultsInRange( Date fromDate, Date toDate, int state, String triggeredBy,
755 int projectGroupId )
756 {
757 PersistenceManager pm = getPersistenceManager();
758
759 Transaction tx = pm.currentTransaction();
760
761 try
762 {
763 tx.begin();
764
765 pm.getFetchPlan().addGroup( BUILD_RESULT_WITH_DETAILS_FETCH_GROUP );
766
767 Extent extent = pm.getExtent( BuildResult.class, true );
768
769 Query query = pm.newQuery( extent );
770
771 String parameters = "";
772 String filter = "";
773
774 Map params = new HashMap();
775
776 int ctr = 0;
777
778 if ( state > 0 )
779 {
780 params.put( "state", state );
781 ctr++;
782 parameters += "int state, ";
783 filter += "this.state == state && ";
784 }
785
786 if ( projectGroupId > 0 )
787 {
788 params.put( "projectGroupId", projectGroupId );
789 ctr++;
790 parameters += "int projectGroupId, ";
791 filter += "this.project.projectGroup.id == projectGroupId && ";
792 }
793
794 if ( triggeredBy != null && !triggeredBy.equals( "" ) )
795 {
796 params.put( "triggeredBy", triggeredBy );
797 ctr++;
798 query.declareImports( "import java.lang.String" );
799 parameters += "String triggeredBy, ";
800 filter += "this.username == triggeredBy && ";
801 }
802
803 if ( fromDate != null )
804 {
805 params.put( "fromDate", fromDate.getTime() );
806 ctr++;
807 parameters += "long fromDate, ";
808 filter += "this.startTime >= fromDate && ";
809 }
810
811 if ( toDate != null )
812 {
813 Calendar cal = Calendar.getInstance();
814 cal.setTime( toDate );
815 cal.add( Calendar.DAY_OF_MONTH, 1 );
816
817 params.put( "toDate", cal.getTimeInMillis() );
818 ctr++;
819 parameters += "long toDate";
820 filter += "this.startTime < toDate";
821 }
822
823 if ( filter.endsWith( "&& " ) )
824 {
825 filter = filter.substring( 0, filter.length() - 3 );
826 parameters = parameters.substring( 0, parameters.length() - 2 );
827 }
828
829 query.declareParameters( parameters );
830 query.setFilter( filter );
831
832 List<BuildResult> result = (List<BuildResult>) query.executeWithMap( params );
833
834 result = (List<BuildResult>) pm.detachCopyAll( result );
835
836 tx.commit();
837
838 return result;
839 }
840 finally
841 {
842 rollback( tx );
843 }
844 }
845 }