Как удалить процедуру или функцию из базы данных

При разработке инструментов, которые взаимодействуют с разными СУБД, приходится учитывать много нюансов, потому что одни и теже вещи реализованы по-разному и стандарт SQL поддерживается по-разному. Если рассмотреть достаточное количество СУБД, то окажется, что нет универсального способа удалить функцию или процедуру.

Читать далее Как удалить процедуру или функцию из базы данных

Добавление настроек к отдельным файлам в CMake

CMake поддерживает следующие команды для добавления настроек к цели:

  • target_compile_definitions — добавляет определения,
  • target_compile_options — добавляет опции компилятора,
  • target_include_directories — добавляет пути поиска заголовочных файлов,
  • target_link_libraries — добавляет линкуемые библиотеки.

Эти команды принимают имя цели в качестве первого аргумента. Цели создаются командами add_executable и add_library. Для add_executable целью является исполняемый файл, а для add_library — библиотека (статическая или динамическая).

CMake поддерживает следующие команды для добавления глобальных настроек:

  • add_compile_definitions — добавляет определения,
  • add_compile_options — добавляет опции компилятора,
  • include_directories — добавляет пути поиска заголовочных файлов.
  • link_libraries — добавляет линкуемые библиотеки.

Эти настройки применяются к целям в текущей папке и всех вложенных папках.

Команды для настройки целей и глобальные команды очень похожи, но имеют разную область видимости. К сожалению, нет аналогичных команд для настройки исходных файлов.

Чтобы добавить настройки к исходному файлу, можно воспользоваться командой set_property или set_source_files_properties. Пример использования:

set_property(SOURCE LibPQExt.cpp PROPERTY INCLUDE_DIRECTORIES
    ${CMAKE_SOURCE_DIR}/libs/postgresql-9.6/src/include
)

set_property позволяет добавлять настройки для нескольких исходных файлов одновременно.

Более удобный способ — создать из исходного файла или их набора специальную цель, которая называется объектной библиотекой.

Синтаксис команды для создания объектных библиотек:

add_library(<name> OBJECT <src>...)

К такой цели можно применять команды с префиксом target_. Например, можно добавить определение LOGGER_TYPE=3 только для файла logger.cpp. Делается это следующим образом

add_library(logger OBJECT logger.cpp)
target_compile_definitions(logger PUBLIC LOGGER_TYPE=3)

Объектную библиотеку можно добавить к другим целям как набор исходных файлов. Для этого в команды add_executable или add_library надо добавить выражение $<TARGET_OBJECTS:objlib>, где objlib — имя объектной библиотеки. Например:

add_library(logger OBJECT logger.cpp)
target_compile_definitions(logger PUBLIC LOGGER_TYPE=3)

add_executable(my_application
    main.cpp
    archiver.cpp
    $<TARGET_OBJECTS:logger>
)

Поддержка объектных библиотек была введена в CMake версии 2.8.8 (апрель 2012 года). При использовании объектных библиотек рекомендуется в файле CMakeLists.txt ограничить версию CMake на уровне 2.8.8 или выше:

cmake_minimum_required(VERSION 2.8.8)

Комиссии на Etsy и Ebay

Размер комиссии в валюте рассчитывается по следующей формуле.

\left( P\cdot\frac{E1}{100} + E2 \right) \cdot \left( \frac{V}{100} + 1 \right)

(P * E1/100 + E2) * (V/100 + 1)

Где:

  • P — цена товара (вместе с доставкой), валюта;
  • E1 — комиссия магазина от цены товара, %;
  • E2 — фиксированная комиссия магазина, валюта;
  • V — российский НДС, %.

Примечания:

  • НДС взимается не с цены товара, а с комиссии магазина.
  • Фиксированная комиссия на Ebay равна 0.
  • Комиссия Ebay составляет 10 % от цены товара.
  • Фиксированная комиссия на Etsy составляет 0,2 доллара США и берется за публикацию товара.
  • Комиссия Etsy составляет 5 % от цены товара.

Настройка общей папки в VirtualBox

В статье приводится способ настройки общей папки, когда на виртуальной машине установлен Linux, в частности Ubuntu 18.04.

Первым делом нужно установить дополнения гостевой ОС.

Подключение образа дополнений гостевой ОС в VirtualBox
Подключаем образ диска дополнений гостевой ОС.
Запускам установщик дополнений в появившемся окне.

В настройках виртуальной машины нужно выбрать общие папки. Нужно поставить галочки «Авто-подключение» и «Создать постоянную папку.»

VirtualBox выбор общей папки

После сохранения настроек, на рабочем столе виртуальной машины появится папка с префиксом sf_. Это и есть общая папка.

Но пока в эту папку нет доступа. Чтобы доступ появился, нужно добавить своего пользователя в группу vboxsf. Это делается в терминале с помощью следующей команды.

sudo usermod -a -G vboxsf <USERNAME>

Где вместо <USERNAME>, нужно указать ваше имя пользователя.

Доступ в папку откроется после перезагрузки виртуальной машины.

С++: Типобезопасное перечисление (enum class) в unordered_map

Это статья о языке программирования C++.

Элементы обычного перечисление (enum) запросто могут применяться в качестве ключа в unordered_map. Следующий пример показывает, как сопоставить элемент перечисления с текстовым значением.

#include <string>
#include <iostream>
#include <unordered_map>

enum Color { Red, Blue, Green, };

int main()
{
    std::unordered_map<int, std::string> colors {
        {Red, "Red"},
        {Blue, "Blue"},
        {Green, "Green"},
    };
    
    std::cout << colors.at(Red) << std::endl;
}

Выполнить код.

Этот пример выведет в консоль слово «Red». Заметьте, что тип ключа — int.

Такое перечисление не типобезопасно и устарело. Язык C++11 предоставляет типобезопасные перечисления (enum class). У такого перечисления для доступа к элементам надо указывать имя перечисления.

Ниже приведен пример типобезопасного перечисления.

enum class Month
{
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December,
};

Чтобы получить доступ к элементу January, нужно написать Month::January.

Элементы такого перечисления можно использовать в аналогичном unordered_map, но только с явным привидением типа с помощью static_cast. Пример:

int main()
{
    std::unordered_map<int, std::string> colors{
        {static_cast<int>(Month::January), "January"},
        {static_cast<int>(Month::February), "February"},
    };
    
    std::cout << colors.at(static_cast<int>(Month::January)) << std::endl;
}

Использование static_cast делает код громоздким.

Код ниже показывает, как создать unordered_map, у которого в качестве ключа элементы типобезопасного перечисления, и где не требуется приведение типа.

#include <string>
#include <iostream>
#include <unordered_map>

struct EnumClassHash
{
    template <typename T>
    std::size_t operator()(T t) const
    {
        return static_cast<std::size_t>(t);
    }
};

enum class Month
{
    January,
    February,
    March,
    April,
    May,
    June,
    July,
    August,
    September,
    October,
    November,
    December,
};

int main()
{
    std::unordered_map<Month, std::string, EnumClassHash> months{
        {Month::January,   "January"},
        {Month::February,  "February"},
        {Month::March,     "March"},
        {Month::April,     "April"},
        {Month::May,       "May"},
        {Month::June,      "June"},
        {Month::July,      "July"},
        {Month::August,    "August"},
        {Month::September, "September"},
        {Month::October,   "October"},
        {Month::November,  "November"},
        {Month::December,  "December"},
    };
    
    std::cout << months.at(Month::January) << std::endl;
}

Выполнить код.

Ключевую роль здесь играет класс EnumClassHash. Он указывается в качестве шаблонного параметра при объявлении unordered_map. Этот класс возвращает хеш от элемента перечисления, при чем делает это максимально эффективным способом. В качестве хеша выступает значение самого элемента перечисления.

Таким образом можно создавать сколько угодно unordered_map c различными перечислениями, используя один единственный класс EnumClassHash. Иначе пришлось бы в пространстве имен std определять хеш-функцию для каждого перечисления.

Данный способ почерпнут в одном вопросе на StackOverflow.

Быстрая ручная нарезка провода МГТФ

Установка Time Doctor на Ubuntu 18.04

UPD: Статья более не актуальна. Вы можете скачать Time Doctor с офиального сайта.

На данный момент нет версии Time Doctor для недавно вышедшей Ubuntu 18.04.

В инструкции приведен способ установки Time Doctor для Ubuntu 16.04 на Ubuntu 18.04. Все действия выполняются в командной строке.

    1. Добавим репозитории от Ubuntu 16.04. Для этого создадим и откроем файл /etc/apt/sources.list.d/ubuntu16_04.list следующей командой:
      sudo nano /etc/apt/sources.list.d/ubuntu16_04.list
    2. Вставим в файл следующий список репозиториев:
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial main restricted
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial-updates main restricted
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial universe
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial-updates universe
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial multiverse
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial-updates multiverse
      deb http://ru.archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse
      deb http://security.ubuntu.com/ubuntu xenial-security main restricted
      deb http://security.ubuntu.com/ubuntu xenial-security universe
      deb http://security.ubuntu.com/ubuntu xenial-security multiverse
      
    3. Сохраним файл комбинацией клавиш Ctrl+O и закроем комбинацией Ctrl+X.
    4. Обновим базу пакетов следующей командой:
      sudo apt update
    5. Установим зависимости следующей командой:
      sudo apt install libssl1.0-dev libx11-xcb1 libxcb1 libssl1.0.0 libqtcore4 libqtgui4 libqt4-dbus libqt4-network libqt4-sql libqt4-sql-sqlite libqt4-svg libqt4-xml libqt4-xmlpatterns gksu gdebi libjpeg8 libpng12-0 libcv2.4 libxcb-record0
      
    6. Качаем Time Doctor для Ubuntu 16.04 c официального сайта.
    7. Устанавливаем скаченный пакет следующей командой (название файла можем отличаться):
      sudo dpkg -i timedoctorlite_2.3.49-14ubuntu16.04_amd64.deb
    8. Пакет должен успешно установиться.
    9. Запускаем Time Doctor и проверяем, что все работает. Запустить можно следующей командой (если у вас Lite-версия):
      timedoctorlite
    10. Восстанавливаем исходное состояние пакетов в системе
      sudo rm /etc/apt/sources.list.d/ubuntu16_04.list
      sudo apt update
    11. Ставим лайк статье, если она оказалась полезной. Или пишем в комментариях, что у вас не получилось.

Получение пользовательского токена от eBay

В статье описывается:

  • Взаимодействие продавца с сайтом приложения и с сайтом eBay для предоставления приложению токена.
  • Получение токена приложением.
    1. Продавец заходит на сайт приложения и нажимает кнопку “Войти” или иным способом сообщает приложению, что намеревается им воспользоваться.
    2. Приложение отправляет к eBay запрос GetSessionID, в котором указывает URL для перенаправления. Приложение получает в ответ SessionID, который будет идентифицировать продавца, когда он войдет на eBay. Примеры запроса GetSessionID.
    3. Приложение перенаправляет пользователя на страницу входа eBay. URL этой страницы формируется с использованием SessionID и URL для перенаправления. Формат формируемого URL следующий:
    4. Продавец входит на eBay.
      Форма входа eBay
    5. eBay перенаправляет продавца на форму подтверждения, чтобы он дал согласие на предоставление доступа приложению. Вид формы определяется настройками.
    6. Когда продавец кликает кнопку “I agree”, eBay перенаправляет его по адресу, который указан в настройках в поле “Your auth accepted URL”.
    7. Когда продавец попадает по этому адресу, приложение посылает к eBay запрос FetchToken, содержащий SessionID, и в ответ получает токен. Примеры запроса FetchToken. Это один из немногих запросов, который требует учетные данные приложения. То есть, чтобы сделать запрос, приложение должно добавить в HTTP-заголовок следующие данные: App ID, Dev ID и Cert ID.
      Для большинства других запросов учетные данные не требуются. Вместо них приложение добавляет токен в RequesterCredentials. Если используется SOAP, то RequesterCredentials должен быть в заголовке SOAP. Если используется XML, то RequesterCredentials включается в тело запроса. Дополнительные сведения см. в разделе Security на странице Making a Trading API Call.
    8. Запрос FetchToken возвращает приложению пользовательский токен продавца и срок годности токена. Приложение сохраняет эти данные для дальнейшего использования.
    9. Приложение делает запрос GeteBayOfficialTime, чтобы проверить новый токен.

Ссылки

  1. Оригинальная статья Getting a Token for a User.

 

Минимальный проект «Hello, World!» с помощью Java и Gradle

Gradle — это набирающая популярность система автоматической сборки проектов на языке Java.

Проект должен содержать минимум два файла:

  • build.gradle — файл конфигурации сборки Gradle.
  • Файл с исходным кодом на языке Java, например Main.java.

Важна структура папок. build.gradle должен находиться в корневой папке проекта. Файл Main.java должен находиться в папке «src/main/java».

Структура проекта должна быть, как на следующей картинке.
Java Gradle Project Structure

Содержимое файла Main.java следующее.

public class Main {
    public static void main (String[] args) {
        System.out.println("Hello, world!");
    }
}

Содержимое файла build.gradle следующее.

apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'Main'

jar {
    manifest {
        attributes 'Main-Class': mainClassName
    }
}

В этом файле подключаются плагины, которые предоставляет все необходимо для сборки. Кроме того, в файле указывается точка входа программы — это класс Main.

Проект собирается командой gradle build, которую нужно выполнить в папке проекта. После чего создается папка build/libs, в которой можно найти исполняемый jar-файл.

Запустить программу можно следующей командой.

java -jar build/libs/project_name.jar

Или с помощью Gradle следующей командой.

gradle run

Такой проект можно открыть в IDE NetBeans. Для этого в NetBeans должен быть установлен плагин Gradle Support. Чтобы установить плагин, нужно запустить меню Tools -> Plugins и в диалоговом окне найти Gradle Support.

Успехов.

Аргументы командной строки в разных языках программирования

C и C++

int  main(int argc, char* argv[])
{
    argc;    // количество аргументов + 1
    argv[0]; // имя программы
    argv[1]; // первый аргумент
    argv[2]; // второй аргумент
    // ...
}

Bash

#!/bin/bash

# $# — количество аргументов
#
# $* — аргументы одной строкой
# $@ — список аргументов

echo $0    # имя скрипта
echo $1    # первый аргумент
echo $2    # второй аргумент
# ...
echo $9    # девятый аргумент
echo $(10) # десятый аргумент
echo $(11) # одиннадцатый аргумент
# ...

Cmd.exe

echo %0 REM имя срипта
echo %1 REM первый аргумент
echo %2 REM первый аргумент
REM ...
echo %9 REM девятый аргумент

Python

import sys

sys.argv      # список аргументов
len(sys.argv) # количество аргументов + 1
sys.argv[0]   # имя скрипта
sys.argv[1]   # первый аргумент
sys.argv[2]   # второй аргумент
# ...

Java

public class CommandLine {
    static public void main(String args[]) {
        args.length; // количество аргументов
        args[0];     // первый аргумент
        args[1];     // второй аргумент
        // ...
    }
}

C Sharp

class MainClass
{
    static int Main(string[] args)
    {
        args.Length; // количество аргументов
        args[0];     // первый аргумент
        args[1];     // второй аргумент
        // ...
    }
}