Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdarg.h>
- #include <libpq-fe.h>
- #define MAX_LINE_SIZE 100
- #define MAX_FILE_LINES 100
- #define FILE_EXTENSION_CSV "csv"
- #define TRUE 1
- #define FALSE 0
- typedef struct Columns
- {
- char** Names;
- int Count;
- } Columns;
- typedef struct ListOfColumns
- {
- Columns** List;
- int Count;
- } ListOfColumns;
- int GetColumnsCount(char* line)
- {
- int columnsCount = 1;
- int i;
- for (i = 0; i < strlen(line); i++)
- {
- if (line[i] == ';')
- columnsCount++;
- }
- return columnsCount;
- }
- char** GetColumnsNames(char* line, int columnsCount)
- {
- char** names = malloc(columnsCount * sizeof(char*));
- int columnIndex = 0;
- char* columnName = strtok(line, ";");
- while (columnName != NULL)
- {
- names[columnIndex] = malloc(sizeof(char) * strlen(columnName));
- strcpy(names[columnIndex++], columnName);
- columnName = strtok(NULL, ";");
- }
- return names;
- }
- // Remove end of line character sequence from the specified line
- void RemoveEndOfLineFrom(char* line)
- {
- int length = strlen(line);
- if (length == 0)
- return;
- char* last = &line[length - 1];
- if (*last == '\n') // Unix and Windows
- {
- *last = '\0';
- if (length > 1)
- {
- char* beforeLast = &line[length - 2];
- if (*beforeLast == '\r') // Windows
- *beforeLast = '\0';
- }
- }
- }
- Columns* ParseLine(char* line)
- {
- RemoveEndOfLineFrom(line);
- // Parse line
- Columns* columns = malloc(sizeof(Columns));
- columns->Count = GetColumnsCount(line);
- columns->Names = GetColumnsNames(line, columns->Count);
- return columns;
- }
- void DoSQL(PGconn *conn, char *command)
- {
- printf("%s\n", command);
- PGresult* result = PQexec(conn, command);
- printf("status is : %s\n", PQresStatus(PQresultStatus(result)));
- printf("#rows affected: %s\n", PQcmdTuples(result));
- printf("result message: %s\n", PQresultErrorMessage(result));
- switch(PQresultStatus(result)) {
- case PGRES_TUPLES_OK:
- {
- int n = 0, m = 0;
- int nrows = PQntuples(result);
- int nfields = PQnfields(result);
- printf("number of rows returned = %d\n", nrows);
- printf("number of fields returned = %d\n", nfields);
- for(m = 0; m < nrows; m++) {
- for(n = 0; n < nfields; n++)
- printf(" %s = %s", PQfname(result, n),PQgetvalue(result,m,n));
- printf("\n");
- }
- }
- }
- PQclear(result);
- }
- char* GetSqlQuery(char* tableName, ...)
- {
- char* query = malloc(sizeof(char) * 1000);
- va_list list;
- va_start(list, tableName);
- char* str;
- do
- {
- str = va_arg(list, char*);
- strcat(query, str);
- }
- while (strcmp(str, ";") != 0);
- va_end(list);
- return query;
- }
- char* GetSqlQueryCreateTable(char* tableName, Columns* columns)
- {
- char* query = malloc(sizeof(char) * 1000); // C sucks, Go calculate size manually LOL
- strcat(query, "CREATE TABLE ");
- strcat(query, tableName);
- strcat(query, "\n(\n");
- strcat(query, columns->Names[0]);
- strcat(query, " VARCHAR(30) UNIQUE,\n");
- int i;
- for (i = 1; i < columns->Count - 1 ;i++)
- {
- strcat(query, columns->Names[i]);
- strcat(query, " VARCHAR(30),\n");
- }
- strcat(query, columns->Names[i]);
- strcat(query, " VARCHAR(30)\n");
- strcat(query, ")");
- return query;
- }
- char* GetSqlQueryInsert(char* tableName, Columns* columns)
- {
- char* query = calloc(1000, sizeof(char)); // C sucks, Go calculate size manually LOL
- strcat(query, "INSERT INTO ");
- strcat(query, tableName);
- strcat(query, " VALUES(");
- int i;
- for (i = 0; i < columns->Count - 1; i++)
- {
- strcat(query, "'");
- strcat(query, columns->Names[i]);
- strcat(query, "', ");
- }
- strcat(query, "'");
- strcat(query, columns->Names[i]);
- strcat(query, "'");
- strcat(query, ")");
- return query;
- }
- char* GetSqlQueryDropTable(char* tableName)
- {
- char* command = "DROP TABLE ";
- char* query = calloc(strlen(command) + strlen(tableName) + 1, sizeof(char)); // + 1 for NULL
- strcat(query, command);
- strcat(query, tableName);
- return query;
- }
- char* ChopFileExtension(char* fileName)
- {
- char* extensionSuffix = strrchr(fileName, '.');
- while(*extensionSuffix != '\0')
- {
- *extensionSuffix = '\0';
- extensionSuffix++;
- }
- return fileName;
- }
- ListOfColumns* ReadFile(FILE* file)
- {
- char line[MAX_LINE_SIZE];
- ListOfColumns* columnsList = malloc(sizeof(ListOfColumns));
- columnsList->List = malloc(sizeof(Columns*) * MAX_FILE_LINES);
- int columnsIndex = 0;
- // Read file line by line
- while (fgets(line, MAX_LINE_SIZE, file) != NULL)
- {
- Columns* columns = ParseLine(line);
- columnsList->List[columnsIndex++] = columns;
- columnsList->Count++;
- }
- return columnsList;
- }
- // Returns:
- // NOT NULL = SUCCESS
- // NULL = FAILURE
- FILE* OpenFile(char* fileName)
- {
- FILE* file = fopen(fileName, "r");
- if (file == NULL)
- {
- printf("Error: unable to open file %s. Please make sure the file exists.", fileName);
- perror(NULL);
- }
- return file;
- }
- // Creates a table defined in a file
- // Table name equals file name wthout extension
- void CreateTableFromFile(char* fileName)
- {
- FILE* file = OpenFile(fileName);
- if (file == NULL)
- {
- return EXIT_FAILURE;
- }
- ListOfColumns* columnsList = ReadFile(file);
- PGconn* conn = PQconnectdb("host=localhost port=5432 dbname=kjercha user=kjercha password=");
- if (PQstatus(conn) == CONNECTION_OK)
- {
- puts("Connection made");
- char* tableName = ChopFileExtension(fileName);
- char* dropTableQuery = GetSqlQueryDropTable(tableName);
- DoSQL(conn, dropTableQuery);
- char* createTableQuery = GetSqlQueryCreateTable(tableName, columnsList->List[0]);
- DoSQL(conn, createTableQuery);
- int i;
- for (i = 1; i < columnsList->Count; i++)
- {
- Columns* columns = columnsList->List[i];
- char* insertQuery = GetSqlQueryInsert(tableName, columns);
- DoSQL(conn, insertQuery);
- }
- }
- else
- printf("connection failed: %s\n", PQerrorMessage(conn));
- PQfinish(conn);
- }
- // Returns:
- // 1 = TRUE if file name has specified extension,
- // 0 = FALSE otherwise
- int FileNameHasExtension(char* fileName, char* extension)
- {
- char* extensionSeparator = strrchr(fileName, '.');
- if (extensionSeparator == NULL)
- return FALSE;
- char* fileExtension = ++extensionSeparator;
- if (strcmp(fileExtension, extension) == 0)
- return TRUE;
- return FALSE;
- }
- // Returns:
- // 1 = TRUE if there is only one argument in the form "fileName.csv"
- // 0 = FALSE any other case
- int ProgramArgumentsAreCorrect(int argc, char* fileName)
- {
- if (argc != 2)
- {
- puts("Error: Incorrect number of program arguments. Only one argument is accepted. Example usage: ./program fileName.csv");
- return FALSE;
- }
- if (!FileNameHasExtension(fileName, FILE_EXTENSION_CSV))
- {
- printf("Error: File name extension is not %s", FILE_EXTENSION_CSV));
- return FALSE;
- }
- return TRUE:
- }
- int main(int argc, char *argv[])
- {
- char* fileName = argv[1];
- if (!ProgramArgumentsAreCorrect(argc, fileName))
- {
- return EXIT_FAILURE;
- }
- CreateTableFromFile(fileName);
- return EXIT_SUCCESS;
- }
Add Comment
Please, Sign In to add comment