v1
This commit is contained in:
188
src/app/api/import-json/route.ts
Normal file
188
src/app/api/import-json/route.ts
Normal file
@@ -0,0 +1,188 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { MongoClient, Db, Collection, ObjectId } from 'mongodb';
|
||||
|
||||
// MongoDB connection
|
||||
let client: MongoClient | null = null;
|
||||
let db: Db | null = null;
|
||||
|
||||
async function getDatabase(): Promise<Db> {
|
||||
if (!client) {
|
||||
const uri = process.env.MONGODB_URI || 'mongodb://localhost:27017';
|
||||
client = new MongoClient(uri);
|
||||
await client.connect();
|
||||
db = client.db('beanstalk');
|
||||
}
|
||||
return db!;
|
||||
}
|
||||
|
||||
function convertMongoExtendedJSON(obj: any): any {
|
||||
if (obj === null || obj === undefined) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
return obj.map(item => convertMongoExtendedJSON(item));
|
||||
}
|
||||
|
||||
if (typeof obj === 'object') {
|
||||
const converted: any = {};
|
||||
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
if (key === '$oid' && typeof value === 'string') {
|
||||
return new ObjectId(value);
|
||||
} else if (key === '$date' && typeof value === 'string') {
|
||||
return new Date(value);
|
||||
} else {
|
||||
converted[key] = convertMongoExtendedJSON(value);
|
||||
}
|
||||
}
|
||||
|
||||
return converted;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const filename = searchParams.get('file');
|
||||
|
||||
if (!filename) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'file parameter is required',
|
||||
message: 'Usage: /api/import-json?file=db_prod.akademyObservations.json'
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Read JSON file
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const filePath = path.join(process.cwd(), '..', filename);
|
||||
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
||||
const rawDocuments = JSON.parse(fileContent);
|
||||
|
||||
// Convert MongoDB extended JSON to proper MongoDB documents
|
||||
const documents = rawDocuments.map((doc: any) => convertMongoExtendedJSON(doc));
|
||||
|
||||
// Get MongoDB collection
|
||||
const db = await getDatabase();
|
||||
const collection = db.collection('observations');
|
||||
|
||||
// Insert documents
|
||||
const result = await collection.insertMany(documents);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: `Successfully imported ${result.insertedCount} observations`,
|
||||
inserted_count: result.insertedCount,
|
||||
inserted_ids: Object.values(result.insertedIds)
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('Import error:', error);
|
||||
|
||||
if (error.code === 'ENOENT') {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'File not found',
|
||||
message: `The file was not found`
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
if (error.name === 'SyntaxError') {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to parse JSON',
|
||||
message: error.message
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to import data',
|
||||
message: error.message
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
const formData = await request.formData();
|
||||
const file = formData.get('file') as File;
|
||||
|
||||
if (!file) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'No file provided',
|
||||
message: 'Please select a JSON file to upload'
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Validate file type
|
||||
if (!file.type.includes('json')) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Invalid file type',
|
||||
message: 'Please upload a JSON file'
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
// Read file content
|
||||
const fileContent = await file.text();
|
||||
const rawDocuments = JSON.parse(fileContent);
|
||||
|
||||
// Convert MongoDB extended JSON to proper MongoDB documents
|
||||
const documents = rawDocuments.map((doc: any) => convertMongoExtendedJSON(doc));
|
||||
|
||||
// Get MongoDB collection
|
||||
const db = await getDatabase();
|
||||
const collection = db.collection('observations');
|
||||
|
||||
// Insert documents
|
||||
const result = await collection.insertMany(documents);
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: `Successfully imported ${result.insertedCount} observations from ${file.name}`,
|
||||
inserted_count: result.insertedCount,
|
||||
inserted_ids: Object.values(result.insertedIds),
|
||||
filename: file.name,
|
||||
size: `${(file.size / 1024).toFixed(2)} KB`
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('Import error:', error);
|
||||
|
||||
if (error.name === 'SyntaxError') {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to parse JSON',
|
||||
message: error.message
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Failed to import data',
|
||||
message: error.message
|
||||
},
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user