пятница, 21 апреля 2017 г.

Kubuntu 16.04 + VirtualBox 5.1.18

Kubuntu 16.04 + VirtualBox 5.1.18
после установки дополнения гостевой ОС, рабочий стол накрылся.
Да и прочие экраны логина накрылись.
Бэкап рулит.

среда, 19 апреля 2017 г.

Firebird + Ubuntu

Запуск firebird 2.5 под Убунтой (16.04):

service firebird2.5-super start

ну или какую другую версию вы выбрали

Каталог для UDF:
/usr/lib/firebird/2.5/UDF
Каталог для конфига:
/etc/firebird/2.5/


Импорт библиотек под Linux

Чтобы можно было слинковать наше приложение или библиотеку с другой - она должна быть в каталоге с соответствующей SDK.
(например, C:\Users\User\Documents\Embarcadero\Studio\SDKs\ubuntu16.04.sdk\)
Так что, боюсь, написание многобиблиотечных приложений под Linux пока будет непростым.


Посмотрим же почему у нас приложения под Linux такие большие:
1) Большой самый основной модуль - System (релизный) - 1280 Кб
причём импортируются всего две бибилотеки:
libicuuc.so
libicui18n.so
Ну и в сам System включается куча всяческих POSIX.XXX модулей

SysInit - 300Кб

Как говорится, во-первых, не было снарядов...

воскресенье, 16 апреля 2017 г.

Delphi + Linux

Один из клиентов пожаловался, что для нашей базы под Firebird нужна UDF, а её нет под линукс.
Решил взяться за это, сделал себе виртуалку, ставлю на неё последнюю KUbuntu 17.04 (наверно, все баги исправлены, все дела))))

Из коробки - подхватился роутер, получил IP
Сайты не открываются.
Ок, прописал гугловский красивый ДНС.
Яндекс открывается, Лазарус открывается, ubuntu.com - нет.

стал рыть,  - ifconfig из коробки нет.
Нашел таки что это какой-то новый механизм разрешения имён:
http://news.softpedia.com/news/ubuntu-16-10-yakkety-yak-switches-to-a-universal-local-dns-resolver-service-504770.shtml
рецепт из  https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1624320  не помог.

Решил попробовать PAServer от новой дельфи - на OpenSuse x64 42.3 - падает с Segmentation fault из под обычного юзера
из под рута - молча ничего не делает и сразу закрывается.
Так как Embarcadero задекларировали что поддерживают с Ubuntu 16.04 LTS, поставил её.
Однако тут не всё так хорошо - в отличие от Suse, она не берет адрес от роутера (настройки VirtualBox такие же как и у Suse)
Хотя прекрасно пингует и роутер и хост Win8

Оказалось, что Ubuntu не приемлет NAT (который подходит для Suse)  - только сетевой мост.

В итоге, после заведения SDK для Линукса
В процессе которого вы, наверняка, увидите не одно сообщение о дублировании имен файлов, получим такой вот
После того как я скомпилировал и запустил приложение из среды, я...
Ничего не увидел! :)
Видимо, не предусмотрели опций для ввода/вывода из под отладчика.
потому что надо было:
1) Enabling Use launcher application in the Run|Parameters
2) Установить XTerm 

(наверняка можно использовать и другой терминал, если помнять по умолчанию опцию в проекте (раздел Debugger, "Use launcher application") с "/usr/bin/xterm -e "%debuggee%" на что-то другое")

простой пример
program LinuxTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Classes;

var
  s: TStringList;
begin
  try

    { TODO -oUser -cConsole Main : Insert code here }
    s := TStringList.Create;
    try
      s.Add('Проверка!');
      s.SaveToFile('/home/user1/UTF8.txt', TEncoding.UTF8);
      s.SaveToFile('/home/user1/win1251.txt', TEncoding.GetEncoding(1251));
    finally
      s.Free;
    end;
  except

    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
прекрасно создал файлы, который Kate - Advanced Text Editor прекрасно понял и распознал кодировку.

Кстати, а запускается программа под отладку из каталога
/home/user1/PAServer/scratch-dir/User-Ubuntu/LinuxTest
/home/user1/PAServer/ - здесь у меня распакован PAServer

А еще скоро будет семинар - 19 апреля


понедельник, 8 августа 2016 г.

Книга по БД

http://www.arbinada.com/node/1372
Надо будет купить, почитать.

воскресенье, 29 мая 2016 г.

VmWare и расшаренные каталоги

Чтобы организовать расшаренные папки в OpenSuse, пришлось воспользоваться советом
https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2016514

четверг, 29 октября 2015 г.

ZEOS DB

Посмотрел (глянул мельком) компоненты доступа ZEOS
Жаль, что нет специального управления транзакциями.

четверг, 2 июля 2015 г.

За что я люблю  Delphi -  можно довольно легко поменять среду кое в чём.
Надо было увеличить ширину, чтобы не лазить по двум строкам вкладок, и видеть все строки VersionInfo.
Restorator 2007 помог мне в том:

четверг, 21 мая 2015 г.

Демонстрация мобильного приложения

Искал чем можно показать экран мобильного приложения, чтобы можно было вывести на большой экран проектора, и нашел сервис http://www.mobizen.com

Для моего Samsung Galaxy Core 2 Dual прекрасно подошёл.

среда, 20 мая 2015 г.

Таймауты

 Черт побери, почему именно 5 секунд на вызов обратной функции, Карл?!

procedure TDSClientCallbackChannelManager.Invoke(const Id: string;
  Data: TJSONValue; out Response: TJSONValue);
var
  Item: TDSCallbackItem;
  Callback: TDBXCallback;
  ExecThread: TDSExecuteThread;
begin
  TMonitor.Enter(FLocalCallbackRepo);
  try
    if FLocalCallbackRepo.TryGetValue(Id, Item) then
    begin
      Callback := Item.Callback;
      try
        TMonitor.Enter(Callback);
        ExecThread := TDSExecuteThread.Create(Callback, Data);

        if not TMonitor.Wait(Callback, 5000) then
          ExecThread.Terminate;

        Response := ExecThread.Response;

среда, 13 мая 2015 г.

Потихоньку ваяю клиент-серверное приложение, применяя Datasnap Callback.
На время ожидания обработки запроса сервером буду показывать popup-форму ожидания, закрывающуюся по обработчику OnTerminate потока.
Естественно, это уже не анонимный поток, а специфический.

Ещё появилась необходимость передавать вызов процедуры с большим количеством параметров с сервера на клиент.
Пока что сделал регистрацию клиентской функции и ручками разворачиваю JSON в набор параметров.
Не хватает автоматической генерации обвязки как у серверных методов.

Есть мысль попробовать сделать Datasnap-сервер на клиенте и подключаться к нему...

вторник, 18 ноября 2014 г.

Программист должен быть "отцом". Иначе - вайп.

понедельник, 3 ноября 2014 г.

XE7 - Дизайнер форм

Одна из непривычных вещей, которую я обнаружил в XE7 - это измененный дизайнер.
Более никаких точных по размерам форм - только резиновый слой.
6 форм-факторов под Андроид с примерными размерами.

правда, мой 5" Galaxy S4 определялся как 4"-ый телефон, но это не существенно - контролы отображались примерно так же как и на макете.


Непростая часть - расположить контролы на макете так, чтобы они перемещались самостоятельно на основе правил.
Тут помогают слои (TLayout) с новыми видами выравнивания, например Align = HorzCenter

вторник, 2 сентября 2014 г.

Всякий раз, когда я берусь описывать что же я сделал по поставленной задаче, сразу как-то лучше понимаю, что же конкретно я сделал.

воскресенье, 17 ноября 2013 г.

Пример использования DataSnap Callback: запрос данных во время вызова серверного метода

Что это и для чего надо:
Работа с Datasnap  заключается в запросе от сервера данных и вызове серверных методов, например:
 - Запросить список товаров с сервера (dataset )
 - Создать новый документ
 - Добавить в него позиции
 - Закрыть документ

Иногда при добавлении позиции необходимо сделать дополнительный выбор, например выбрать партию товара или разрез.

    Это можно сделать через возврат кода ошибки (что-то вроде Prepare/Execute), чтобы клиент запросил пользователя, а затем попробовал снова выполнить операцию.
    Или же дать серверу возможность запросить клиента непосредственно во время операции все необходимые ему данные.

Первый вариант требует перечня кодов ошибок с соответствующей обработкой.
Второй вариант требует зарегистрировать клиенту функции обратного вызова, которые может вызывать сервер, а также при каждом обращении к серверу иметь в виду, что в ответ сервер может что-то потребовать от клиента (а это грозит блокировкой, если запрос требует реакции от пользователя). Для того, чтобы не было блокировок при однопоточном пользовательском интерфейсе, обращения к серверу нужно делать в отдельном потоке - тогда пришедший от сервера вызов можно синхронизировать с основным потоком (который уже не ждет возврата управления от исходного вызова серверного метода). А также не забывать сообщать серверу ID клиента.

Вызов:
procedure TForm2.btnRegisterWareClick(Sender: TObject);
begin
  TThread.CreateAnonymousThread(
    procedure()
    begin
      clmClient.ServerMethods1Client.RegisterWare(seWareID.Value, clmClient.DSClientCallbackChannelManager1.ManagerId)
    end).Start;
end;

Сама функция обратного вызова:
  TmyCallback = class(TDBXCallback)
  protected
    FSelectedString: Integer;
    procedure SelectString(const Arg: TJSONValue);
  public
    function Execute(const Arg: TJSONValue): TJSONValue; override;
  end;

{ TmyCallback }

function TmyCallback.Execute(const Arg: TJSONValue): TJSONValue;
begin
  TThread.Synchronize(nil, procedure()  // запрос данных у пользователя - только в основном потоке
    begin
      SelectString(Arg);
    end);
  Result := TJSONNumber.Create(FSelectedString);
end;

procedure TmyCallback.SelectString(const Arg: TJSONValue);
var
  strs: TStringList;
  enum: TJSONPairEnumerator;
  val, str: string;
begin
  enum := TJSONObject(Arg).GetEnumerator;
  if Assigned(enum) then
  begin
    strs := TStringList.Create;
    try
      while enum.MoveNext do
      begin
        Val:= enum.Current.JsonString.Value;
        str := enum.Current.JsonValue.Value;
        strs.AddObject(str, TObject(val.ToInteger()));
      end;
      FSelectedString := TfrmSelectString.SelectString(strs);
    finally
      strs.Free;
    end;
  end;
  enum.Free;
end;

А вот что происходит на сервере:

procedure TServerMethods1.RegisterWare(ID: Integer; ClientID: string);
var
  Params, ParamsServ: TJSONObject;
  ResObj: TJSONValue;
  temp: TJSONValue;
begin
  ResObj := nil;
  Params := TJSONObject.Create;
  Params.AddPair(TJSONPair.Create('1', 'Размер 42'));
  Params.AddPair(TJSONPair.Create('2', 'Размер 43'));
  Params.AddPair(TJSONPair.Create('3', 'Размер 44'));
  ParamsServ := TJSONObject(Params.Clone);  //Делаем копию для себя, ибо ушедшую не вернуть
 ServerContainer1.DSServer1.NotifyCallback(ClientID, 'SelectString', Params, ResObj);
  if Assigned(ResObj) then
    begin
      temp := ParamsServ.GetValue(ResObj.Value);
      if Assigned(temp) then
        Form1.QueueLogMsg(Format('RegisterWare %d с разрезом %s', [ID, temp.ToString]))
      else
        Form1.QueueLogMsg(Format('RegisterWare %d без разреза', [ID]));
      ResObj.Free;
      ParamsServ.Free;
    end
  else
    Form1.QueueLogMsg(Format('RegisterWare %d без разреза', [ID]));
end;

И напоследок напоминание:
 - Локальные переменные процедур - не инициализируются
 - Всё, что вы передаете в функцию - можете попрощаться с ними и не освобождать
 - Всё, что вы получаете из функции - надо освободить (ведь тут ARC не работает (хотя, надо уточнить для мобилок))

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

Код: https://github.com/VladimirSrednikh/datasnap-callback-with-ui

Так как пока с технологией жестко не определился, следующее изучение будет по TRealThinkClient

воскресенье, 10 ноября 2013 г.

Настроил себе точку доступа на D-Link DWA-125 при помощи утилиты Connectify.
Советы с поднятием SoftAP вручную провалились:
 - Динамически адрес подключенному смартфону не выдал => подключения не происходит.
 - при указании статического адреса соединение рвется непонятно почему.

P.S. Нет,  Connectify тоже не спасение. Время от времени смартфон отключался от свистка и переподключался на домашний роутер с Wi-Fi'ем.
Почему?

P.P.S. Запустил на работе - за 40 минут 20 переподключений. Очень плохо.

понедельник, 4 ноября 2013 г.

Пример дизайнера форм FMX

https://drive.google.com/file/d/0B-o0lV3HGn-JcWNUWHhNM3ZYVEk/edit?usp=sharing
Можно кидать на панельку контролы, двигать, изменять размеры.

Есть также дерево объектов, правда пока без редактирования.

суббота, 2 ноября 2013 г.

Oxygene под Андроид

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

четверг, 31 октября 2013 г.

Xamarin

Решил попробовать сделать приложение под Андроид в Xamarin.
Открыл AndroidManifest.xml, поменял Target android Version
и не получается сохранить
Проверил ProcMon'ом - никто не держит файл, никаких отлупов.
Но сохранить не может :-)

Upd. Что-то где-то переключил - увидел ругань на несовпадение переводов строк  (исходно были МАКовские).
Разрешил поменять на виндовые - сохранил :)

вторник, 29 октября 2013 г.

Прототип

Делать прототип я начал с Mobile App под платформу Win32, т.к. по сути на планшет будет то же самое - никаких платформо-зависимых вызовов, только дергать сервер получать/отправлять данные.

Сервер пришлось помучать, чтобы заставить обычное VCL-приложение заработать в неосновном потоке (благо всякие окошки удалось отключить)
Заработало.

Начал собирать под Андроид - пришлось довыпиливать из интерфейсных модулей использование VCL-контролов, а также IBX.
Потом долго пытался бороться с 

[DCC Hint] H2596 C:\Users\Public\Documents\RAD Studio\12.0\PlatformSDKs\android-ndk-r8e\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-ld.exe: warning: cannot scan executable section 29 of c:\\program files (x86)\\embarcadero\\rad studio\\12.0\\lib\\Android\\Release/libmidas.a(alchemy.o) for Cortex-A8 erratum because it has no mapping symbols.
пока наконец не понял, что это "всего лишь" Hint а не Error.

Сделал прототип, стал показывать.
Оказалось, что мой wi-fi dongle неустойчиво держит связь,
Т.к. сервер у меня Stateful, помогла смена для серверных объектов LifeCycle на 'Session' (прототип сервера на большее и не допилен).

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

Ну и обратные вызовы я так и не попробовал.