@@ -122,6 +122,57 @@ pub trait ISeasonAndAudition<TContractState> {
122122 fn is_audition_paused (self : @ TContractState , audition_id : felt252 ) -> bool ;
123123 fn is_audition_ended (self : @ TContractState , audition_id : felt252 ) -> bool ;
124124 fn audition_exists (self : @ TContractState , audition_id : felt252 ) -> bool ;
125+
126+ // Genre-based filtering
127+ fn get_seasons_by_genre (
128+ self : @ TContractState , genre : felt252 , max_results : u32 ,
129+ ) -> Array <Season >;
130+ fn get_auditions_by_genre (
131+ self : @ TContractState , genre : felt252 , max_results : u32 ,
132+ ) -> Array <Audition >;
133+
134+ // Time-based queries
135+ fn get_active_auditions (self : @ TContractState , current_timestamp : u64 ) -> Array <Audition >;
136+ fn get_auditions_in_time_range (
137+ self : @ TContractState , start_timestamp : u64 , end_timestamp : u64 ,
138+ ) -> Array <Audition >;
139+
140+ // Season-based queries
141+ fn get_auditions_by_season (self : @ TContractState , season_id : felt252 ) -> Array <Audition >;
142+
143+ // Analytics functions
144+ fn get_audition_vote_count (self : @ TContractState , audition_id : felt252 ) -> u32 ;
145+ fn get_total_vote_weight_for_performer (
146+ self : @ TContractState , audition_id : felt252 , performer : felt252 ,
147+ ) -> felt252 ;
148+
149+ // Pagination and listing
150+ fn get_seasons_by_ids (self : @ TContractState , season_ids : Array <felt252 >) -> Array <Season >;
151+ fn get_auditions_by_ids (self : @ TContractState , audition_ids : Array <felt252 >) -> Array <Audition >;
152+
153+ // Complex filtering
154+ fn get_auditions_by_criteria (
155+ self : @ TContractState ,
156+ audition_ids : Array <felt252 >,
157+ genre : Option <felt252 >,
158+ season_id : Option <felt252 >,
159+ start_time : Option <u64 >,
160+ end_time : Option <u64 >,
161+ paused_state : Option <bool >,
162+ ) -> Array <Audition >;
163+
164+ // Utility functions
165+ fn is_audition_active (
166+ self : @ TContractState , audition_id : felt252 , current_timestamp : u64 ,
167+ ) -> bool ;
168+ fn get_audition_status (
169+ self : @ TContractState , audition_id : felt252 ,
170+ ) -> felt252 ; // 0=not_started, 1=active, 2=ended, 3=paused, 404= Not found
171+ fn count_votes_for_audition (
172+ self : @ TContractState ,
173+ audition_id : felt252 ,
174+ voter_performer_pairs : Array <(felt252 , felt252 )>,
175+ ) -> u32 ;
125176}
126177
127178#[starknet:: contract]
@@ -176,6 +227,16 @@ pub mod SeasonAndAudition {
176227 audition_winner_amounts : Map <felt252 , (u256 , u256 , u256 )>,
177228 /// price distributed status
178229 price_distributed : Map <felt252 , bool >,
230+ // For efficient querying - maintain lists of IDs
231+ all_season_ids : Map <u32 , felt252 >, // index -> season_id
232+ all_audition_ids : Map <u32 , felt252 >, // index -> audition_id
233+ season_count : u32 ,
234+ audition_count : u32 ,
235+ // Vote counting cache
236+ audition_vote_counts : Map <felt252 , u32 >, // audition_id -> vote_count
237+ performer_total_weights : Map <
238+ (felt252 , felt252 ), felt252 ,
239+ > // (audition_id, performer) -> total_weight
179240 }
180241
181242 #[event]
@@ -302,6 +363,10 @@ pub mod SeasonAndAudition {
302363 . entry (season_id )
303364 . write (Season { season_id , genre , name , start_timestamp , end_timestamp , paused });
304365
366+ let current_count = self . season_count. read ();
367+ self . all_season_ids. write (current_count , season_id );
368+ self . season_count. write (current_count + 1 );
369+
305370 self . emit (SeasonCreated { season_id , genre , name });
306371 }
307372
@@ -346,7 +411,9 @@ pub mod SeasonAndAudition {
346411 audition_id , season_id , genre , name , start_timestamp , end_timestamp , paused ,
347412 },
348413 );
349-
414+ let current_count = self . audition_count. read ();
415+ self . all_audition_ids. write (current_count , audition_id );
416+ self . audition_count. write (current_count + 1 );
350417 self . emit (AuditionCreated { audition_id , season_id , genre , name });
351418 }
352419
@@ -555,6 +622,13 @@ pub mod SeasonAndAudition {
555622
556623 self . votes. entry (vote_key ). write (Vote { audition_id , performer , voter , weight });
557624
625+ let current_count = self . audition_vote_counts. read (audition_id );
626+ self . audition_vote_counts. write (audition_id , current_count + 1 );
627+
628+ let performer_key = (audition_id , performer );
629+ let current_weight = self . performer_total_weights. read (performer_key );
630+ self . performer_total_weights. write (performer_key , current_weight + weight );
631+
558632 self . emit (Event :: VoteRecorded (VoteRecorded { audition_id , performer , voter , weight }));
559633 }
560634
@@ -656,6 +730,276 @@ pub mod SeasonAndAudition {
656730 let audition = self . auditions. entry (audition_id ). read ();
657731 audition . audition_id != 0
658732 }
733+
734+ // Genre-based filtering
735+ fn get_seasons_by_genre (
736+ self : @ ContractState , genre : felt252 , max_results : u32 ,
737+ ) -> Array <Season > {
738+ let mut result = ArrayTrait :: new ();
739+ let mut count = 0 ;
740+ let total_seasons = self . season_count. read ();
741+
742+ let mut i = 0 ;
743+ while i < total_seasons && count < max_results {
744+ let season_id = self . all_season_ids. read (i );
745+ if season_id != 0 {
746+ let season = self . seasons. read (season_id );
747+ if season . genre == genre {
748+ result . append (season );
749+ count += 1 ;
750+ }
751+ }
752+ i += 1 ;
753+ };
754+
755+ result
756+ }
757+
758+ fn get_auditions_by_genre (
759+ self : @ ContractState , genre : felt252 , max_results : u32 ,
760+ ) -> Array <Audition > {
761+ let mut result = ArrayTrait :: new ();
762+ let mut count = 0 ;
763+ let total_auditions = self . audition_count. read ();
764+
765+ let mut i = 0 ;
766+ while i < total_auditions && count < max_results {
767+ let audition_id = self . all_audition_ids. read (i );
768+ if audition_id != 0 {
769+ let audition = self . auditions. read (audition_id );
770+ if audition . genre == genre {
771+ result . append (audition );
772+ count += 1 ;
773+ }
774+ }
775+ i += 1 ;
776+ };
777+
778+ result
779+ }
780+
781+ // Time-based queries
782+ fn get_active_auditions (self : @ ContractState , current_timestamp : u64 ) -> Array <Audition > {
783+ let mut result = ArrayTrait :: new ();
784+ let total_auditions = self . audition_count. read ();
785+
786+ let mut i = 0 ;
787+ while i < total_auditions {
788+ let audition_id = self . all_audition_ids. read (i );
789+ if audition_id != 0 {
790+ let audition = self . auditions. read (audition_id );
791+ if self . is_audition_active (audition_id , current_timestamp . into ()) {
792+ result . append (audition );
793+ }
794+ }
795+ i += 1 ;
796+ };
797+
798+ result
799+ }
800+
801+ fn get_auditions_in_time_range (
802+ self : @ ContractState , start_timestamp : u64 , end_timestamp : u64 ,
803+ ) -> Array <Audition > {
804+ let mut result = ArrayTrait :: new ();
805+ let total_auditions : u32 = self . audition_count. read (). try_into (). unwrap ();
806+
807+ let mut i = 0_u32 ;
808+ while i < total_auditions {
809+ let audition_id = self . all_audition_ids. read (i );
810+ if audition_id != 0 {
811+ let audition = self . auditions. read (audition_id );
812+ if audition . start_timestamp. try_into (). unwrap () >= start_timestamp
813+ && audition . end_timestamp. try_into (). unwrap () <= end_timestamp {
814+ result . append (audition );
815+ }
816+ }
817+ i += 1 ;
818+ };
819+
820+ result
821+ }
822+
823+ // Season-based queries
824+ fn get_auditions_by_season (self : @ ContractState , season_id : felt252 ) -> Array <Audition > {
825+ let mut result = ArrayTrait :: new ();
826+ let total_auditions = self . audition_count. read ();
827+
828+ let mut i = 0 ;
829+ while i < total_auditions {
830+ let audition_id = self . all_audition_ids. read (i );
831+ if audition_id != 0 {
832+ let audition = self . auditions. read (audition_id );
833+ if audition . season_id == season_id {
834+ result . append (audition );
835+ }
836+ }
837+ i += 1 ;
838+ };
839+
840+ result
841+ }
842+
843+ // Analytics functions
844+ fn get_audition_vote_count (self : @ ContractState , audition_id : felt252 ) -> u32 {
845+ self . audition_vote_counts. read (audition_id )
846+ }
847+
848+ fn get_total_vote_weight_for_performer (
849+ self : @ ContractState , audition_id : felt252 , performer : felt252 ,
850+ ) -> felt252 {
851+ self . performer_total_weights. read ((audition_id , performer ))
852+ }
853+
854+ // Pagination and listing
855+ fn get_seasons_by_ids (self : @ ContractState , season_ids : Array <felt252 >) -> Array <Season > {
856+ let mut result = ArrayTrait :: new ();
857+ let season_ids_span = season_ids . span ();
858+
859+ for season_id in season_ids_span {
860+ let season = self . seasons. read (* season_id );
861+ if season . season_id != 0 {
862+ result . append (season );
863+ }
864+ };
865+
866+ result
867+ }
868+
869+ fn get_auditions_by_ids (
870+ self : @ ContractState , audition_ids : Array <felt252 >,
871+ ) -> Array <Audition > {
872+ let mut result = ArrayTrait :: new ();
873+ let audition_ids_span = audition_ids . span ();
874+
875+ for audition_id in audition_ids_span {
876+ let audition = self . auditions. read (* audition_id );
877+ if audition . audition_id != 0 {
878+ result . append (audition );
879+ }
880+ };
881+
882+ result
883+ }
884+
885+ // Complex filtering
886+ fn get_auditions_by_criteria (
887+ self : @ ContractState ,
888+ audition_ids : Array <felt252 >,
889+ genre : Option <felt252 >,
890+ season_id : Option <felt252 >,
891+ start_time : Option <u64 >,
892+ end_time : Option <u64 >,
893+ paused_state : Option <bool >,
894+ ) -> Array <Audition > {
895+ let mut result = ArrayTrait :: new ();
896+ let audition_ids_span = audition_ids . span ();
897+
898+ for audition_id in audition_ids_span {
899+ let audition = self . auditions. read (* audition_id );
900+ if audition . audition_id == 0 {
901+ continue ;
902+ }
903+
904+ // Apply filters
905+ if let Option :: Some (filter_genre ) = genre {
906+ if audition . genre != filter_genre {
907+ continue ;
908+ }
909+ }
910+
911+ if let Option :: Some (filter_season_id ) = season_id {
912+ if audition . season_id != filter_season_id {
913+ continue ;
914+ }
915+ }
916+
917+ if let Option :: Some (filter_start_time ) = start_time {
918+ if audition . start_timestamp. try_into (). unwrap () < filter_start_time {
919+ continue ;
920+ }
921+ }
922+
923+ if let Option :: Some (filter_end_time ) = end_time {
924+ if audition . end_timestamp. try_into (). unwrap () > filter_end_time {
925+ continue ;
926+ }
927+ }
928+
929+ if let Option :: Some (filter_paused ) = paused_state {
930+ if audition . paused != filter_paused {
931+ continue ;
932+ }
933+ }
934+
935+ result . append (audition );
936+ };
937+
938+ result
939+ }
940+
941+ // Utility functions
942+ fn is_audition_active (
943+ self : @ ContractState , audition_id : felt252 , current_timestamp : u64 ,
944+ ) -> bool {
945+ let audition = self . auditions. read (audition_id );
946+ if audition . audition_id == 0 || audition . paused {
947+ return false ;
948+ }
949+
950+ audition . start_timestamp. try_into (). unwrap () <= current_timestamp
951+ && (audition . end_timestamp == 0
952+ || audition . end_timestamp. try_into (). unwrap () > current_timestamp )
953+ }
954+
955+ /// returns 404 if not found
956+ /// 0 = Not started
957+ /// 1 = Active
958+ /// 2 = Ended
959+ /// 3 = Paused
960+ fn get_audition_status (self : @ ContractState , audition_id : felt252 ) -> felt252 {
961+ let audition = self . auditions. read (audition_id );
962+ if audition . audition_id == 0 {
963+ return 404 ; // Not found
964+ }
965+
966+ if audition . paused {
967+ return 3 ; // Paused
968+ }
969+
970+ let current_time = get_block_timestamp ();
971+
972+ if audition . start_timestamp. try_into (). unwrap () > current_time {
973+ return 0 ; // Not started
974+ }
975+
976+ if audition . end_timestamp != 0
977+ && audition . end_timestamp. try_into (). unwrap () <= current_time {
978+ return 2 ; // Ended
979+ }
980+
981+ 1 // Active
982+ }
983+
984+ fn count_votes_for_audition (
985+ self : @ ContractState ,
986+ audition_id : felt252 ,
987+ voter_performer_pairs : Array <(felt252 , felt252 )>,
988+ ) -> u32 {
989+ let mut count = 0 ;
990+ let pairs_span = voter_performer_pairs . span ();
991+
992+ for pair in pairs_span {
993+ let (performer , voter ) = * pair ;
994+ let vote_key = (audition_id , performer , voter );
995+ let vote = self . votes. read (vote_key );
996+ if vote . audition_id != 0 {
997+ count += 1 ;
998+ }
999+ };
1000+
1001+ count
1002+ }
6591003 }
6601004
6611005 #[generate_trait]
0 commit comments