📄 dbms.cpp
字号:
//:DBMS.cpp
// DBMS v1.1 数据库系统实现源程序
// 作者:余康华 2002.2.7
// 版权所有 (C) 2002 余康华
//文件大小:DBMS.CPP: 960行 29466 Bytes
// DBMS.EXE: 66462 Bytes
//请在此处加入您的版权信息:
#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <myfunc.h>
#include <ctype.h>
#include <io.h> //For access()
#include <process.h> //For system()
#include <type.h>
#include <menu.h>
#include <mouse.h>
#include "dbms.h"
///Macro definations//////////////////////////////////////////
//#define PSat(x,y,s) gotoxy(x,y);cputs(s)
#define ClrLine(x,y) gotoxy(x,y);clreol()
///Globla Variables///////////////////////////////////////////
TDBF DBF[10]; // Max opened DBFfile at one time
int CurWork=0;
int LastWork=0;
char cmdstr[81];
struct time Time;
int drawflag=1;
int ListLine=5;
/// Function prototypes///////////////////////////////////////
void Quit();
void Help();
void Dir();
////////////////////////////////////////////////////////////
int IsAllSpace(char *s)
{ while(*s) if((*s!=' ')&&(*s!='\n')) return 0;
return 1;
}
void ReadFile(char *buf,int sz,FILE *fp,char stop='\n')
{
char ch;
ch=fgetc(fp);
while((ch!=stop)&&(!feof(fp))&&sz)
{ *buf++=ch; ch=fgetc(fp); }
*buf=0;
}
////////////////////////////////////////////////////////////
// x,y: 起始点坐标
//num: "点"数
//hor: 是否为横(默认值)
void Line(int x,int y,int num,int hor=1)
{
gotoxy(x,y);
if(hor)for(int i=0;i<num;i++) { gotoxy(x+i,y);putch(196);}
else for(int j=0;j<num;j++) { gotoxy(x,y+j);putch(179);}
}
////////////////////////////////////////////////////////////
//在字符方式下 输入一个字符串。
void Input(int x,int y,char *str)
{ char s[80];
s[0]=80;
gotoxy(x,y);
cgets(s);
if(s[1]==0||s[2]==27) strcpy(str,"");
else strcpy(str,s+2);
}
////////////////////////////////////////////////////////////
//在字符方式下 输入一个数值。
void InputInt(int x,int y,int *i)
{
char s[12];
s[0]=10;
gotoxy(x,y);
cgets(s);
if(s[1]==0||s[2]==27) *i=0;
else *i=atoi(s+2);
}
////////////////////////////////////////////////////////////
//TDBF类的构造函数据
TDBF::TDBF(char *fn)
{ strcpy(FileName,fn);
CurRec=Header.Next=0;
Header.Prev=0;
fp=NULL;
RecCount=FieldCount=0;
State=0;
}
////////////////////////////////////////////////////////////
//添加下条记录
void TDBF::Add(int pos)
{
do{
MenuDraw();
if(DBF[CurWork].fp==NULL)
{ Prompt("当前工作区间未打开文件");return;}
clrscr();
gotoxy(1,1);
gettime(&Time);
ClrLine(1,1);
cprintf(" YKH 数据库管理统系-[当前工作区间%c-->%s]",CurWork+'A',DBF[CurWork].FileName);
gotoxy(66,1);
cprintf("[%2d:%2d:%2d]",Time.ti_hour,Time.ti_min,Time.ti_sec);
textcolor(BLUE);
Line(1,4,80);
textcolor(YELLOW);
PSat(30,5,"添加记录");
Line(1,6,80);
TRecord *old=0;
if(pos!=-1&&pos!=0&&pos<=RecCount) // Default position ---before Current record
{ old=CurRec;Goto(pos);}
PSat(1,8,"记录号 #");
gotoxy(1,9);
if(RecCount==0)CurRec->NO=1;
cprintf("%-4d",CurRec->NO);
int len=10;
for(int i=0;i<FieldCount;i++)
{
PSat(len,8,FieldName[i]);
len+=FieldWidth[i]+1;
}
TRecord *T=new TRecord;
T->Next=0;
for(i=0;i<FieldCount;i++)
{ T->Values[i]=new char[FieldWidth[i]+1]; //为一个记录分配空间
if(T->Values[i]==0) { PSat(1,25,"没有足够的内存");getch();return;}
}
len=10;
textbackground(BLUE);
for(i=0;i<FieldCount;i++){
gotoxy(len,9);
for(int j=0;j<FieldWidth[i];j++) putch(' ');
len+=FieldWidth[i]+1;}
len=10;
for(i=0;i<FieldCount;i++){ Input(len,9,T->Values[i]);
len+=FieldWidth[i]+1;}
if(CurRec==0){
RecCount=1;
Header.Next=T;
CurRec=T;
T->NO=1;
T->Next=T->Prev=0;}
else {
T->Next=CurRec->Next;
CurRec->Next=T;
T->Prev=CurRec;
T->NO=CurRec->NO+1;
while(T->Next!=0) { T->Next->NO++; T=T->Next;}
RecCount++;}
textbackground(BLACK);
Modified=1;
if(old!=0) CurRec=old; // to the old position if not use default pos=-1
char c=Prompt("成功插入记录!是否继续[Y/N]<Y>");
if(c=='Y'||c=='y'||c=='\n'||c=='\r') {CurRec=CurRec->Next;continue;}
else break;
}while(1);
}
////////////////////////////////////////////////////////////
void TDBF::ListField()
{
int len=12;
textcolor(RED);
for(int i=0;i<FieldCount;i++)
{ PSat(len,4,FieldName[i]);
len+=FieldWidth[i]+1;
}
PSat(2,4,"记录号#");
textcolor(YELLOW);
}
////////////////////////////////////////////////////////////
void TDBF::List(word start,word end)
{
if(DBF[CurWork].FieldCount<1)
{ gotoxy(30,4);
cputs("当前工作区间没有字段");
return;
}
TRecord *T=Header.Next;
while(T!=0&&T->NO!=start) T=T->Next;
if(T==0) return;
int page=1;
int len=12;
int i;
ListField();
if(end>RecCount) end=RecCount;
while((T->NO-1!=end)&&(T!=0))
{ if(page%21==0) {
ListLine=5;
PSat(1,25,"敲任意键继续...");getch();
ClrLine(1,1);
gettime(&Time);
ClrLine(1,1);
cprintf(" YKH 数据库管理统系-[当前工作区间%c-->%s]",CurWork+'A',DBF[CurWork].FileName);
gotoxy(69,1);
cprintf("[%2d:%2d:%2d]",Time.ti_hour,Time.ti_min,Time.ti_sec);
textcolor(BLUE); Line(1,2,80);
textcolor(RED);
ListField();
}
len=12;
textcolor(CYAN);
gotoxy(3,ListLine);
cprintf("%-6d",T->NO);
page++;
textcolor(YELLOW);
Line(1,4,80);
for( i=0;i<FieldCount;i++){
PSat(len,ListLine,T->Values[i]);
len+=FieldWidth[i]+1;
}
if(T->Flag=='D'){ PSat(2,ListLine,"*"); } /// if it have flag
if(T->NO==CurRec->NO){ PSat(1,ListLine,">");}
ListLine++;
len=12;
T=T->Next;
}
}
////////////////////////////////////////////////////////////
void TDBF::Release()
{
TRecord *T=Header.Next;
while(T->Next!=0) T=T->Next;
TRecord *r=T=T->Prev;
while(T!=Header.Next) {delete T->Next;T=r;r=T->Prev; }
delete Header.Next;
Modified=0; Header.Next=CurRec=0; RecCount=0; State=0;
}
////////////////////////////////////////////
void TDBF::Save()
{
if(!Modified) return;
if(fp==NULL) { Prompt("还没有打开任何文件!");return;}
fseek(fp,0,0);
putw(0x5432,fp); //add into a file flag
putw(FieldCount,fp);
putw(RecCount,fp);
char qq[20];
for(int i=0;i<FieldCount;i++)
{ itoa(FieldWidth[i],qq,10);
fputs(FieldName[i],fp);
fputc('\n',fp);
fputs(qq,fp);
fputc('\n',fp);
}
TRecord *T=Header.Next;
for(i=0;i<RecCount;i++)
{
fputc(T->Flag,fp);
for(int j=0;j<FieldCount;j++)
{ fputs(T->Values[j],fp);
fputc('\n',fp);
}
T=T->Next;
}
Modified=0;
ClrLine(1,25);
Prompt("成功保存文件!");
ClrLine(1,25);
}
///////////////////////////////////////////////////////
void TDBF::Modify(int no)
{
TRecord *old;
if(DBF[CurWork].FieldCount<1)
{ gotoxy(30,4);
cputs("当前工作区间没有字段");
return;
}
if(no!=0) { old=CurRec;Goto(no);}
Modified=1; //will modify
int len=12;
clrscr();
gotoxy(1,1);
gettime(&Time);
ClrLine(1,1);
cprintf(" YKH 数据库管理统系-[当前工作区间%c-->%s]",CurWork+'A',DBF[CurWork].FileName);
gotoxy(69,1);
cprintf("[%2d:%2d:%2d]",Time.ti_hour,Time.ti_min,Time.ti_sec);
textcolor(BLUE); Line(1,2,80);
ListField();
len=12;
gotoxy(3,5);
textcolor(CYAN);
cprintf("%-6d",CurRec->NO);
for(int i=0;i<FieldCount;i++)
{ PSat(len,5,CurRec->Values[i]);
len+=FieldWidth[i]+1;
}
cprintf(" <---记录的旧值");
gotoxy(len,6);
cprintf(" <---新值");
len=12;
if(CurRec->Flag=='D'){ PSat(2,5,"*"); } /// if it have flag
if(CurRec->NO==old->NO){ PSat(1,5,">");}
textbackground(BLUE);
for(i=0;i<FieldCount;i++)
{ gotoxy(len,6);
for(int j=0;j<FieldWidth[i];j++)putch(' '); //draw a lignt bar
len+=FieldWidth[i]+1;
}
len=12;
textcolor(YELLOW);
for(i=0;i<FieldCount;i++)
{ Input(len,6,CurRec->Values[i]);
len+=FieldWidth[i]+1;
}
textbackground(BLACK);
PSat(1,25,"成功修改记录!");
getch();
ClrLine(1,25);
if(no!=0) CurRec=old;
Modified=1;
}
///////////////////////////////////////////////////////
void TDBF::Load(char *fn)
{
FILE *t;
char s[80];
if(fn==NULL)
{
ShowCursor();
ClrLine(1,25);
PSat(1,25,"输入文件名:");
s[0]=70;
cgets(s);
if(s[1]==0||s[2]==27) return;
if(fp!=NULL&&Modified){ //File No save question if save
ClrLine(1,25);
PSat(1,25,"文件被修改,是否保存?[Y/N]<Y>");
char c=getch();
if(c=='Y'||c=='y'||c=='\r'||c=='\n') Save();
Release(); //Relase the old record link
}
}
else strcpy(s+2,fn);
strcat(s,".YDB");
strcpy(FileName,s+2);
t=fopen(FileName,"r+");
if(!t)
{ strcpy(FileName,"Untitled.YDB");
ClrLine(1,25);PSat(1,25,"文件未找到!");getch();return;}
unsigned w;
fseek(fp,0,0);
w=getw(t);
if(w!=0x5432){ Prompt("文件的格式不是正确!");ClrLine(1,25);cputs("命令:");return; }
fp=t;
FieldCount=getw(fp);
RecCount=getw(fp);
char qq[70];
for(int i=0;i<FieldCount;i++)
{ ReadFile(FieldName[i],11,fp);
ReadFile(qq,FieldWidth[i]+1,fp);
FieldWidth[i]=atoi(qq);
}
int num=1;
for(i=0;i<RecCount;i++)
{ TRecord *T=new TRecord;
if(!T) { ClrLine(1,25);PSat(1,25,"没有足够的内存"); getch(); return;}
T->Flag=getc(fp);
for(int j=0;j<FieldCount;j++)
{ T->Values[j]=new char[FieldWidth[j]+1];
if(!T->Values[j]){ ClrLine(1,25);PSat(1,25,"没有足够的内存");getch();return;}
ReadFile(T->Values[j],FieldWidth[j]+1,fp);
}
if(CurRec==0){//最先没有记录
CurRec=T;T->NO=1;CurRec->NO=1;Header.Next=T;T->Prev=T->Next=0;}
else{
T->Next=CurRec->Next; //插入一条记录
T->Prev=CurRec;
CurRec->Next=T;
CurRec=T;
T->NO=++num;}
}
Modified=0;
CurRec=Header.Next;
CurRec->NO=1;
State=1;
Prompt("成功加载文件");
ClrLine(1,25);
}
////////////////////////////////////////////////////////////
void TDBF::Create(char *fn)
{
char s[50];
if(fn==NULL)
{ if(Modified){
char c;
PSat(1,25,"文件未保存,是否保存?[Y/N/C取消]<Y>");
c=getch();
if(c=='y'||c=='Y'||c=='\n'||c=='\r') Save();
if(c=='c'||c=='C') return;
Release();
}
if(fp!=NULL) Close();
PSat(1,25,"输入文件名:");
s[0]=13;
cgets(s);
if(s[1]==0||s[2]==27) return;
strcpy(FileName,s+2);
}
else strcpy(FileName,fn);
strcat(FileName,".YDB");
if(access(FileName,0)==0)
{
ClrLine(1,25);
PSat(1,25,"文件已存在,是否覆盖<Y/N/C取消]<Y>?");
char c=getch();
if(c=='n'||c=='N'||c=='\n'||c=='\r')
{
PSat(1,25,"输入文件名:");
Input(12,25,FileName);
}
else if(c=='c'||c=='C') { strcpy(FileName,"Untitled.YDB");return;}
}
ClrLine(1,25);
gotoxy(1,25);
cputs("输入字段个数:");
s[0]=10;
cgets(s);
if(s[1]==0||s[2]==27) return ;
FieldCount=atoi(s+2) %MAXFIELD;
fp=fopen(FileName,"w+");
if(!fp)
{PSat(1,25,"不能建立文件!");
getch();
strcpy(FileName,"Untitled.YDB");
return;
}
clrscr();
gettime(&Time);
ClrLine(1,1);
gettime(&Time);
ClrLine(1,1);
cprintf(" YKH 数据库管理统系-[当前工作区间%c-->%s]",CurWork+'A',DBF[CurWork].FileName);
gotoxy(69,1);
cprintf("[%2d:%2d:%2d]",Time.ti_hour,Time.ti_min,Time.ti_sec);
textcolor(BLUE); Line(1,2,80);
textcolor(RED);
PSat(20,5,"字段名 字段长度");
Line(1,6,79);
textcolor(YELLOW);
textbackground(BLUE);
for(int n=0;n<FieldCount;n++)
{ PSat(20,7+2*n," ");
PSat(43,7+2*n," ");
}
int allwidth=10;
for( n=0;n<FieldCount;n++)
{ FNAG: Input(20,7+2*n,FieldName[n]);
if(FieldName[n][0]==0){
textbackground(BLACK);
PSat(1,25,"请输入一个字段名");
textbackground(BLUE);
goto FNAG;}
FWAG: InputInt(43,7+2*n,&FieldWidth[n]);
if(FieldWidth[n]<1){
textbackground(BLACK);
PSat(1,25,"请输入一个正整数");
textbackground(BLUE);
goto FWAG;}
allwidth+=FieldWidth[n];
}
if(allwidth>80){ // total the widths exceed 80 characters
int est=0; // if that, choose a lengthest field and decreae it
for( n=1;n<FieldCount;n++)
if(FieldWidth[est]<FieldWidth[n]) est=n;
FieldWidth[est]-=(80-allwidth);
}
textbackground(BLACK);
PSat(1,25,"成功建立文件,现在输入记录吗?[Y/N]<Y>");
char ch=getch();
if(ch=='y'||ch=='Y'||ch=='\n'||ch=='\r') Add();
Modified=1;
State=1;
}
////////////////////////////////////////////////////////////
void TDBF::Close()
{
if(fp==NULL) return;
if(Modified&&fp!=NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -