This is msqldump.c in view mode; [Download] [Up]
/*
** msqldump.c - Dump a tables contents and format to an ASCII file
**
**
** Original version written by Igor Romanenko (igor@frog.kiev.ua) under
** the name of msqlsave.c and placed in the public domain. This program
** remains in the public domain to continue the spirit of its original
** author although the modifications made to the original program are :-
**
** Copyright (c) 1994 David J. Hughes
**
**
** This software is provided "as is" without any expressed or implied warranty.
**
** The author's original notes follow :-
**
** ******************************************************
** * *
** * MSQLSAVE.C -- saves the contents of an mSQL table *
** * in .msql format. *
** * *
** * AUTHOR: Igor Romanenko (igor@frog.kiev.ua) *
** * DATE: December 3, 1994 *
** * WARRANTY: None, expressed, impressed, implied *
** * or other *
** * STATUS: Public domain *
** * *
** ******************************************************
*/
#include <stdio.h>
#include <common/portability.h>
#include "msql.h"
/* Exit codes */
#define EX_USAGE 1
#define EX_MSQLERR 2
#define EX_CONSCHECK 3
char usage[] = "\n\n\
usage: %s [-h host] [-v] database [table]\n\n\
Produce an ASCII dump of a database table or an entire database\n\n";
int verbose = 0;
int sock = -1;
char insert_pat[5 * 1024];
/*
** DBerror -- prints mSQL error message and exits the program.
*/
void DBerror()
{
fprintf(stderr, "mSQL error: %s\n", msqlErrMsg);
if ( sock != -1 )
msqlClose(sock);
exit(EX_MSQLERR);
}
char *escapeText(str)
char *str;
{
register char *cp,
*cp2,
*tmp;
int numQuotes;
cp = str;
numQuotes = 0;
while((cp = (char *)index(cp,'\'')))
{
numQuotes++;
cp++;
}
if (numQuotes)
{
tmp = (char *)malloc(strlen(str)+numQuotes+1);
cp2 = tmp;
cp = str;
while(*cp)
{
if (*cp == '\'')
*cp2++='\\';
*cp2++ = *cp++;
}
*cp2 = '\0';
return(tmp);
}
else
{
return((char *)strdup(str));
}
}
/*
** dbConnect -- connects to the host and selects DB.
** Also checks whether the tablename is a valid table name.
*/
void dbConnect(host,database)
char *host,
*database;
{
if (verbose)
{
fprintf(stderr, "Connecting to %s...\n",
host ? host : "localhost");
}
sock = msqlConnect(host);
if ( sock == -1 )
DBerror();
if ( verbose )
fprintf(stderr, "Selecting data base %s...\n", database);
if ( msqlSelectDB(sock, database) == -1 )
DBerror();
}
/*
** dbDisconnect -- disconnects from the host.
*/
void dbDisconnect(host)
char *host;
{
if (verbose)
{
fprintf(stderr, "Disconnecting from %s...\n",
host ? host : "localhost");
}
msqlClose(sock);
}
/*
** getStructure -- retrievs database structure, prints out corresponding
** CREATE statement and fills out insert_pat.
*/
int getTableStructure(table)
char *table;
{
m_field *mf;
m_result *tableRes;
int init = 1,
numFields;
if (verbose)
{
fprintf(stderr, "Retrieving table structure for table %s...\n",
table);
}
if (!(tableRes = msqlListFields(sock, table)))
{
fprintf(stderr, "mSQL error: No such table - %s\n", table);
exit(EX_MSQLERR);
}
printf("\n#\n# Table structure for table '%s'\n#\n",table);
sprintf(insert_pat, "INSERT INTO %s VALUES (", table);
printf("CREATE TABLE %s (\n", table);
while(mf=msqlFetchField(tableRes))
{
if (init)
{
init = 0;
}
else
{
printf(",\n");
}
printf(" %s ", mf->name);
switch(mf->type)
{
case INT_TYPE:
printf("INT");
break;
case CHAR_TYPE:
printf("CHAR(%d)", mf->length);
break;
case REAL_TYPE:
printf("REAL");
break;
default:
fprintf(stderr, "Unknown field type: %d\n",
mf->type);
exit(EX_CONSCHECK);
}
if(IS_NOT_NULL(mf->flags) )
printf(" NOT NULL");
if(IS_PRI_KEY(mf->flags) )
printf(" PRIMARY KEY");
}
printf("\n) \\g\n\n");
numFields = msqlNumFields(tableRes);
msqlFreeResult(tableRes);
return(numFields);
}
/*
** dumpTable saves database contents as a series of INSERT statements.
*/
void dumpTable(numFields,table)
int numFields;
char *table;
{
char query[48],
*tmp;
m_result *res;
m_field *field;
m_row row;
int i;
int init = 1;
if (verbose)
fprintf(stderr, "Sending SELECT query...\n");
printf("\n#\n# Dumping data for table '%s'\n#\n\n",table);
sprintf(query, "SELECT * FROM %s", table);
if (msqlQuery(sock, query) == -1)
DBerror();
if (!(res=msqlStoreResult()))
DBerror();
if (verbose)
{
fprintf(stderr, "Retrieved %d rows. Processing...\n",
msqlNumRows(res) );
}
if (msqlNumFields(res) != numFields)
{
fprintf(stderr,"Error in field count! Aborting.\n\n");
exit(EX_CONSCHECK);
}
while (row=msqlFetchRow(res))
{
printf("%s", insert_pat);
init = 1;
msqlFieldSeek(res,0);
for (i = 0; i < msqlNumFields(res); i++)
{
if (!(field = msqlFetchField(res)))
{
fprintf(stderr,"Not enough fields! Aborting\n");
exit(EX_CONSCHECK);
}
if (!init )
printf(",");
else
init=0;
if (row[i])
{
if (field->type == CHAR_TYPE)
{
tmp = escapeText(row[i]);
printf("\'%s\'", tmp);
free(tmp);
}
else
{
printf("%s", row[i]);
}
}
else
{
printf("NULL");
}
}
printf(")\\g\n");
}
}
char *getTableName()
{
static m_result *res = NULL;
m_row row;
if (!res)
{
res = msqlListTables(sock);
if (!res)
return(NULL);
}
row = msqlFetchRow(res);
if (row)
{
return((char *)row[0]);
}
else
{
msqlFreeResult(res);
return(NULL);
}
}
main(argc, argv)
int argc;
char *argv[];
{
int c,
numRows,
errFlag = 0;
char *host = NULL,
*database = NULL,
*table = NULL;
extern char *optarg;
extern int optind;
/*
** Check out the args
*/
while((c=getopt(argc,argv,"h:v"))!= -1)
{
switch(c)
{
case 'h':
if (host)
errFlag++;
else
host = optarg;
break;
case 'v':
if (verbose)
errFlag++;
else
verbose++;
break;
case '?':
errFlag++;
}
}
if (errFlag)
{
fprintf(stderr,usage, argv[0]);
exit(EX_USAGE);
}
if (optind < argc)
database = argv[optind++];
if (optind < argc)
table = argv[optind++];
if (!database)
{
fprintf(stderr,usage, argv[0]);
exit(EX_USAGE);
}
printf("#\n# mSQL Dump (requires mSQL-1.0.6 or better)\n#\n");
printf("# Host: %s Database: %s\n",
host ? host : "localhost", database);
printf("#--------------------------------------------------------\n\n");
dbConnect(host,database);
if (table)
{
numRows = getTableStructure(table);
dumpTable(numRows,table);
}
else
{
while((table = getTableName()))
{
numRows = getTableStructure(table);
dumpTable(numRows,table);
}
}
dbDisconnect(host);
printf("\n");
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.