add tag api

This commit is contained in:
monoid 2022-06-29 21:14:39 +09:00
parent 8758e78f88
commit 253311bbd7
7 changed files with 103 additions and 25 deletions

View File

@ -1,10 +1,16 @@
import {Knex as k} from "knex";
export namespace Knex {
export const config = {
export const config: {
development: k.Config,
production: k.Config
} = {
development: {
client: 'sqlite3',
connection: {
filename: './devdb.sqlite3'
}
},
debug: true,
},
production: {
client: 'sqlite3',

View File

@ -4,10 +4,23 @@ import {Knex as KnexConfig} from './config';
import { get_setting } from './SettingConfig';
export async function connectDB(){
const config = KnexConfig.config;
const env = get_setting().mode;
const init_need = !existsSync(config[env].connection.filename);
const knex = Knex(config[env]);
const config = KnexConfig.config[env];
if(!config.connection){
throw new Error("connection options required.");
}
const connection = config.connection
if(typeof connection === "string"){
throw new Error("unknown connection options");
}
if(typeof connection === "function"){
throw new Error("connection provider not supported...");
}
if(!("filename" in connection) ){
throw new Error("sqlite3 config need");
}
const init_need = !existsSync(connection.filename);
const knex = Knex(config);
let tries = 0;
for(;;){
try{

View File

@ -3,7 +3,7 @@ import {Knex} from 'knex';
import {createKnexTagController} from './tag';
import { TagAccessor } from '../model/tag';
type DBTagContentRelation = {
export type DBTagContentRelation = {
doc_id:number,
tag_name:string
}

View File

@ -1,5 +1,6 @@
import {Tag, TagAccessor} from '../model/tag';
import {Tag, TagAccessor, TagCount} from '../model/tag';
import {Knex} from 'knex';
import {DBTagContentRelation} from './doc';
type DBTags = {
name: string,
@ -11,7 +12,12 @@ class KnexTagAccessor implements TagAccessor{
constructor(knex:Knex){
this.knex = knex;
}
async getTagAllList(onlyname?:boolean){
async getAllTagCount(): Promise<TagCount[]> {
const result = await this.knex<DBTagContentRelation>("doc_tag_relation").select("tag_name")
.count("*",{as:"occurs"}).groupBy<TagCount[]>("tag_name");
return result;
}
async getAllTagList(onlyname?:boolean){
onlyname = onlyname ?? false;
const t:DBTags[] = await this.knex.select(onlyname ? "*" : "name").from("tags")
return t;

View File

@ -3,10 +3,16 @@ export interface Tag{
description?: string
}
export interface TagAccessor{
getTagAllList: (onlyname?:boolean)=> Promise<Tag[]>
getTagByName: (name:string)=>Promise<Tag|undefined>,
addTag: (tag:Tag)=>Promise<boolean>,
delTag: (name:string) => Promise<boolean>,
updateTag: (name:string,tag:string) => Promise<boolean>
export interface TagCount{
tagname: string;
occurs: number;
}
export interface TagAccessor{
getAllTagList: (onlyname?:boolean)=> Promise<Tag[]>;
getAllTagCount(): Promise<TagCount[]>;
getTagByName: (name:string)=>Promise<Tag|undefined>;
addTag: (tag:Tag)=>Promise<boolean>;
delTag: (name:string) => Promise<boolean>;
updateTag: (name:string,tag:string) => Promise<boolean>;
}

32
src/route/tags.ts Normal file
View File

@ -0,0 +1,32 @@
import {Context, Next} from "koa";
import Router,{RouterContext} from "koa-router";
import { TagAccessor } from "../model/tag";
import { sendError } from "./error_handler";
import { createPermissionCheckMiddleware as PerCheck, Permission } from "../permission/permission";
export function getTagRounter(tagController: TagAccessor){
let router = new Router();
router.get("/",PerCheck(Permission.QueryContent),
async (ctx: Context)=>{
if(ctx.query["withCount"]){
const c = await tagController.getAllTagCount();
ctx.body = c;
}
else {
const c = await tagController.getAllTagList();
ctx.body = c;
}
ctx.type = "json";
});
router.get("/:tag_name", PerCheck(Permission.QueryContent),
async (ctx: RouterContext)=>{
const tag_name = ctx.params["tag_name"];
const c = await tagController.getTagByName(tag_name);
if (!c){
sendError(404, "tags not found");
}
ctx.body = c;
ctx.type = "json";
});
return router;
}

View File

@ -7,25 +7,31 @@ import {DiffManager, createDiffRouter} from './diff/mod';
import { createReadStream, readFileSync } from 'fs';
import getContentRouter from './route/contents';
import { createKnexDocumentAccessor, createKnexUserController } from './db/mod';
import { createKnexDocumentAccessor, createKnexTagController, createKnexUserController } from './db/mod';
import bodyparser from 'koa-bodyparser';
import {error_handler} from './route/error_handler';
import {createUserMiddleWare, createLoginRouter, isAdminFirst, getAdmin} from './login';
import {createInterface as createReadlineInterface} from 'readline';
import { DocumentAccessor, UserAccessor } from './model/mod';
import { DocumentAccessor, UserAccessor, TagAccessor } from './model/mod';
import { createComicWatcher } from './diff/watcher/comic_watcher';
import { getTagRounter } from './route/tags';
class ServerApplication{
readonly userController: UserAccessor;
readonly documentController: DocumentAccessor;
readonly diffManger;
readonly tagController: TagAccessor;
readonly diffManger: DiffManager;
readonly app: Koa;
private index_html:Buffer;
private constructor(userController: UserAccessor,documentController:DocumentAccessor){
this.userController = userController;
this.documentController = documentController;
this.diffManger = new DiffManager(documentController);
private constructor(controller:{
userController: UserAccessor,
documentController:DocumentAccessor,
tagController: TagAccessor}){
this.userController = controller.userController;
this.documentController = controller.documentController;
this.tagController = controller.tagController;
this.diffManger = new DiffManager(this.documentController);
this.app = new Koa();
this.index_html = readFileSync("index.html");
}
@ -66,6 +72,11 @@ class ServerApplication{
const content_router = getContentRouter(this.documentController);
router.use('/api/doc',content_router.routes());
router.use('/api/doc',content_router.allowedMethods());
const tags_router = getTagRounter(this.tagController);
router.use("/api/tags",tags_router.routes());
router.use("/api/tags",tags_router.allowedMethods());
const login_router = createLoginRouter(this.userController);
router.use('/user',login_router.routes());
router.use('/user',login_router.allowedMethods());
@ -75,7 +86,8 @@ class ServerApplication{
let mm_count = 0;
app.use(async (ctx,next)=>{
console.log(`==========================${mm_count++}`);
const fromClient = ctx.state['user'].username === "" ? ctx.ip : ctx.state['user'].username;
const ip = (ctx.get("X-Real-IP")) ?? ctx.ip;
const fromClient = ctx.state['user'].username === "" ? ip : ctx.state['user'].username;
console.log(`${fromClient} : ${ctx.method} ${ctx.url}`);
await next();
//console.log(`404`);
@ -136,8 +148,11 @@ class ServerApplication{
const setting = get_setting();
let db = await connectDB();
const app = new ServerApplication(createKnexUserController(db)
,createKnexDocumentAccessor(db));
const app = new ServerApplication({
userController:createKnexUserController(db),
documentController: createKnexDocumentAccessor(db),
tagController: createKnexTagController(db),
});
await app.setup();
return app;
}