1- /*import { Container } from "@azure/cosmos";
1+ import { Container } from "@azure/cosmos" ;
2+ import { fetchQuestions } from "./repoQuestions" ;
3+ import { getQuestionsContainer } from "./cosmos-client" ;
24
35export const QuestionsDataSource = ( container : Container ) => {
46 return {
@@ -38,7 +40,7 @@ export const QuestionsDataSource = (container: Container) => {
3840 } ,
3941 } ;
4042} ;
41- */
43+
4244export const RepoQuestionsDataSource = ( container : any ) => {
4345 return {
4446 async getQuestion ( id : string ) {
@@ -65,3 +67,150 @@ export const RepoQuestionsDataSource = (container: any) => {
6567 } ,
6668 } ;
6769} ;
70+
71+ // Helper function to extract exam ID from URL
72+ const extractExamId = ( link : string ) : string => {
73+ const segments = link . split ( "/" ) ;
74+ return segments [ segments . length - 3 ] . replace ( / - / g, "_" ) . toLowerCase ( ) ;
75+ } ;
76+
77+ export const CombinedQuestionsDataSource = ( ) => {
78+ return {
79+ async getQuestion ( id : string , link : string ) {
80+ try {
81+ const examId = extractExamId ( link ) ;
82+ const questionsContainer = await getQuestionsContainer ( ) ;
83+
84+ // Try Cosmos DB first (most efficient)
85+ const querySpec = {
86+ query : "SELECT * FROM c WHERE c.id = @id AND c.examId = @examId" ,
87+ parameters : [
88+ { name : "@id" , value : id } ,
89+ { name : "@examId" , value : examId } ,
90+ ] ,
91+ } ;
92+ const { resources : items } = await questionsContainer . items
93+ . query ( querySpec )
94+ . fetchAll ( ) ;
95+
96+ if ( items . length > 0 ) {
97+ return items [ 0 ] ;
98+ }
99+
100+ // Fallback to GitHub if not found in database
101+ const questions = await fetchQuestions ( link ) ;
102+ if ( questions ) {
103+ const question = questions . find ( ( q : any ) => q . id === id ) ;
104+ if ( question ) {
105+ // Add examId to the question document and upload to database
106+ const questionWithExamId = {
107+ ...question ,
108+ examId : examId ,
109+ } ;
110+
111+ try {
112+ await questionsContainer . items . upsert ( questionWithExamId ) ;
113+ } catch ( err ) {
114+ console . warn ( "Failed to upload question to Cosmos DB:" , err ) ;
115+ }
116+ return question ;
117+ }
118+ }
119+
120+ return null ;
121+ } catch ( err ) {
122+ throw new Error ( "Error fetching question: " + err ) ;
123+ }
124+ } ,
125+
126+ async getQuestions ( link : string ) {
127+ try {
128+ const examId = extractExamId ( link ) ;
129+ const questionsContainer = await getQuestionsContainer ( ) ;
130+
131+ // Try Cosmos DB first
132+ const querySpec = {
133+ query : "SELECT VALUE COUNT(c.id) FROM c WHERE c.examId = @examId" ,
134+ parameters : [ { name : "@examId" , value : examId } ] ,
135+ } ;
136+ const { resources : items } = await questionsContainer . items
137+ . query ( querySpec )
138+ . fetchAll ( ) ;
139+
140+ if ( items [ 0 ] > 0 ) {
141+ return { count : items [ 0 ] } ;
142+ }
143+
144+ // Fallback to GitHub if no questions found in database
145+ const questions = await fetchQuestions ( link ) ;
146+ if ( questions ) {
147+ // Upload all questions to database (only if they don't exist)
148+ try {
149+ for ( const question of questions ) {
150+ const questionWithExamId = {
151+ ...question ,
152+ examId : examId ,
153+ } ;
154+ await questionsContainer . items . upsert ( questionWithExamId ) ;
155+ }
156+ } catch ( err ) {
157+ console . warn ( "Failed to upload questions to Cosmos DB:" , err ) ;
158+ }
159+ return { count : questions . length } ;
160+ }
161+
162+ return { count : 0 } ;
163+ } catch ( err ) {
164+ throw new Error ( "Error fetching questions: " + err ) ;
165+ }
166+ } ,
167+
168+ async getRandomQuestions ( range : number , link : string ) {
169+ try {
170+ const examId = extractExamId ( link ) ;
171+ const questionsContainer = await getQuestionsContainer ( ) ;
172+
173+ // Try Cosmos DB first
174+ const querySpec = {
175+ query : "SELECT * FROM c WHERE c.examId = @examId" ,
176+ parameters : [ { name : "@examId" , value : examId } ] ,
177+ } ;
178+ const { resources : items } = await questionsContainer . items
179+ . query ( querySpec )
180+ . fetchAll ( ) ;
181+
182+ if ( items . length > 0 ) {
183+ // Questions exist in database, return random selection
184+ const shuffled = [ ...items ] . sort ( ( ) => 0.5 - Math . random ( ) ) ;
185+ return shuffled . slice ( 0 , range ) ;
186+ }
187+
188+ // Fallback to GitHub if no questions found in database
189+ const questions = await fetchQuestions ( link ) ;
190+ if ( questions ) {
191+ const shuffled = [ ...questions ] . sort ( ( ) => 0.5 - Math . random ( ) ) ;
192+ const selected = shuffled . slice ( 0 , range ) ;
193+
194+ // Upload selected questions to database (only if they don't exist)
195+ try {
196+ for ( const question of selected ) {
197+ const questionWithExamId = {
198+ ...question ,
199+ examId : examId ,
200+ } ;
201+ await questionsContainer . items . upsert ( questionWithExamId ) ;
202+ }
203+ } catch ( err ) {
204+ console . warn ( "Failed to upload questions to Cosmos DB:" , err ) ;
205+ }
206+
207+ return selected ;
208+ }
209+
210+ return [ ] ;
211+ } catch ( err ) {
212+ throw new Error ( "Error fetching random questions: " + err ) ;
213+ }
214+ } ,
215+ } ;
216+ } ;
0 commit comments