Vely logo Empower C
install  tutorials  examples
documentation  license  about

12.1.0 released on Sep 19, 2022

Example upload file



PURPOSE:


Upload file example.

SYNTAX:


See code below.

DESCRIPTION:


File management system:

Files metadata are kept in the database (name, path, description, size, extension), while the files themselves are kept in Vely file_storage.
This example is included in Vely installation. Here is how to compile and run it.

By default, Vely will automatically restart your application when a new executable is produced.

FILES:


The following are the source files for this project.

setup.sql:
create table if not exists files (fileName varchar(100), localPath varchar(300), extension varchar(10), description varchar(200), fileSize int, fileID bigint  auto_increment primary key);

delete_file.v:
// SPDX-License-Identifier: Apache-2.0
// Copyright 2018 DaSoftver LLC.


#include "vely.h" // must always be here


// Delete the file
void delete_file ()
{

    out-header default

    @<h2>Delete a file</h2>

    input-param action
    input-param file_id

    char *file_name = NULL;
    char *desc = NULL;
    char *local_path = NULL;
    // Get file information from the database
    run-query @db="select fileName, localPath, description  from files where fileID='%s'" output fileName, localPath, description : file_id
        query-result fileName to file_name
        query-result description to desc
        query-result localPath to local_path
    end-query

    if (!strcmp (action, "confirm")) {
        // get file information to confirm what will be deleted
        @Are you sure you want to delete file <<p-web file_name>> (<<p-web desc>>)? Click <a href="?req=delete_file&amp;action=delete&amp;file_id=<<p-url file_id>>">Delete</a> or click the browser's Back button to go back.<br/>

    } else if (!strcmp (action, "delete")) {
        // actual delete file, once confirmed
        begin-transaction @db
        run-query @db= "delete from files where fileID='%s'" : file_id error define err no-loop
        if (atol(err) != 0) {
            @Could not delete the file (error <<p-web err>>)
            rollback-transaction @db
        } else {
            delete-file local_path status define st
            if (st == VV_OKAY) {
                commit-transaction @db
                @File deleted. Go back to <a href="?req=start">start page</a>
            } else {
                rollback-transaction @db
                @File could not be deleted, error <<pf-web "%lld", st>>
            }
        }
    } else {
        @Unrecognized action <<p-web action>>
    }

}

do_upload.v:
// SPDX-License-Identifier: Apache-2.0
// Copyright 2018 DaSoftver LLC.


#include "vely.h" // must always be here


// Upload the file
void do_upload ()
{
    out-header default

    // file description from the upload form
    input-param filedesc

    // file name
    input-param file_filename

    // the path to uploaded file
    input-param file_location

    // size in bytes
    input-param file_size

    // the file extension
    input-param file_ext
    VV_UNUSED (file_ext);

    @<h2>Uploading file</h2>

    // insert the information about the file into the database
    run-query @db="insert into files (fileName, localPath, extension, description, fileSize) values ('%s', '%s', '%s', '%s', '%s')": file_filename, file_location, file_ext, filedesc, file_size
    end-query

    @File <<p-web file_filename>> of size <<p-web file_size>> is stored on server at <<p-web file_location>>. File description is <<p-web filedesc>>.<hr/>
}

manage_files.v:
// SPDX-License-Identifier: Apache-2.0
// Copyright 2018 DaSoftver LLC.



#include "vely.h" // must always be here

// Upload the file
void manage_files ()
{

    input-param action

    if (!strcmp (action, "list")) {

        // List current files in the database

        out-header default
        @<h2>List of files</h2>
        @To add a file, <a href="?req=start">click here</a><br/><br/>

        @<table border="1">
        @<tr>
        @    <td>File</td><td>Description</td><td>Size</td><td>Show</td><td>Delete</td>
        @</tr>

        // get the list of files from the database
        run-query @db="select fileName, description, fileSize, fileID from files order by fileSize desc" output fileName, description, fileSize, fileID
            query-result fileName to define file_name
            query-result fileID to define file_ID
            query-result description to define description
            query-result fileSize to define file_size
            // construct table output with links to Show and Delete files
            @<tr>
            @    <td><<p-web file_name>></td><td><<p-web description>><td><<p-web file_size>></td>
            @    <td><a href="?req=manage_files&amp;action=download&amp;file_id=<<p-url file_ID>>">Show</a></td>
            @    <td><a href="?req=delete_file&amp;action=confirm&amp;file_id=<<p-url file_ID>>">Delete</a></td>
            @</tr>
        end-query
        @</table>
    } else if (!strcmp (action, "download")) {

        // Show or download a file (its ID is in the database)

        input-param file_id

        char *local_path=NULL;
        char *ext = NULL;

        // get the local path and extension of the file
        run-query @db="select localPath,extension from files where fileID='%s'" output localPath, extension : file_id row-count define num_files
            query-result localPath to local_path
            query-result extension to ext
        end-query

        // check we can find the file
        if (num_files != 1) {
            out-header default
            @Cannot find this file!<hr/>
            return;
        }

        // display JPG or PDF files in the browser, or download any other kind
        if (!strcmp (ext, ".jpg")) {
            send-file local_path headers content-type "image/jpg"
        } else if (!strcmp (ext, ".pdf")) {
            send-file local_path headers content-type "application/pdf"
        } else {
            send-file local_path headers content-type "application/octet-stream" download
        }

    } else {
        out-header default
        @Unrecognized action <<p-out action>>
    }

}

start.v:
// SPDX-License-Identifier: Apache-2.0
// Copyright 2018 DaSoftver LLC.


#include "vely.h" // must always be here


// Upload and list/download files
void start ()
{

    out-header default

    @<h2>File Manager</h2>

    @To manage the uploaded files, <a href="?req=manage_files&amp;action=list">click here.</a><br/>
    @<br/>

    // Form to upload a file

    @<form action="" method="POST" enctype="multipart/form-data">
    @    <input type="hidden" name="req" value="do_upload">

    @    <label for="file_description">File description:</label><br>
    @    <textarea name="filedesc" rows="3" columns="50"></textarea><br/>
    @    <br/>
    @    <label for="filename">File:</label>
    @    <input type="file" name="file" value=""><br><br>

    @    <input type="submit" value="Submit">
    @</form>

}


SEE ALSO:


Examples ( example_cookies   example_create_table   example_docker   example_form   example_hello_world   examples   example_sendmail   example_stock   example_upload_file   example_write_report  )  SEE ALL (documentation)



Copyright (c) 2022 DaSoftver LLC. Vely is a trademark of Dasoftver LLC. The software and information herein are provided "AS IS" and without any warranties or guarantees of any kind. Icons copyright PaweĊ‚ Kuna licensed under MIT. This web page is licensed under CC-BY-SA-4.0.