asriyanarthur

Table of Contents

Этот сайт является базой знаний.
Пишу обо всём, что хочется сохранить.
Подробнее обо мне можно почитать в соответствующем разделе.
Найти меня в других местах можно по ссылкам: [ Telegram | Mastodon | GitHub ]

Подписаться на обновления данной страницы можно через RSS.

1 Регулярные выражения   regex

1.1 Регулярные выражения в postgres   postgres

Пример SQL запроса с регулярным выражением.
regexp_replace - подходит для построения новой результирующей строки из найденных блоков. обращаться к найденному можно через \1 \2 \3 \4 \5 \6 \7 \8 \9.
\1 - это первая скобка, \2 - вторая. также можно добавить статический текст в результат запроса.

with my_data as (
   select 'some text 1 phone: +7903303333 art' as col union all
   select 'some text 2 phone: +7905505225 who'        union all
   select 'bad string'                                union all
   select 'bad 7903303333' 
)
select d.col,
       regexp_replace(d.col, '^.*phone: \+([0-9]{1,10}).*$|^.*().*$', '\1', 'g') as myregexp_replace,
-- ^.* начинатся с чего угодно
-- в тексте должно быть: "phone: +"
-- после набор цифр от 1 до 10. скобки нужны чтобы обратиться к ним через \1
-- .*$ заканчивается чем угодно
-- | or. нужен для нахождения пустого значения если левая часть не возвращает результат.
-- второй параметр, где указано: '\1' - обращение к найденному в первых скобках.
-- можно также добавить произвольный текст из обратиться также к другим скобкам через \1 \2 \3 ...

      substring(d.col, 'phone: \+([0-9]{1,10})') as mysubstring
-- substring возвращает только результат первых скобок

      --regexp_matches(d.col, 'phone: \+([0-9]{1,10})') as myregexp_matches 
-- regexp_matches - удаляет строки не удовлетворяющие регулярному выражению
-- и возвращает результат в ввиде массива.
  from my_data d
col myregexp_replace mysubstring
some text 1 phone: +7903303333 art 7903303333 7903303333
some text 2 phone: +7905505225 who 7905505225 7905505225
bad string    
bad 7903303333    

Аналогичный пример для поиска значения между тегами без включения самого тега.
Если значение не найдено - возвращаем пустую строку.

with my_data as (
   select ' <html> <tag> this i need </tag> </html>'  as col union all
   select 'bad string without tag'
)
select d.col,
       regexp_replace(d.col, '(.*<tag>(.*?)</tag>.*)|.*().*', '\2', 'g') as myregexp_replace
-- regexp_matches удаляет строки не удовлетворяющие условию регулярного выражения и возвращает результат в ввиде массива
       -- regexp_matches(d.col, '(?<=<tag>).+(?=</tag>)') 
  from my_data d
col myregexp_replace
<html> <tag> this i need </tag> </html> this i need
bad string without tag  

1.2 Регулярные выражения в oracle   oracle

Oracle не поддерживает lookbehind, но можно воспользоваться технологией capture group (обратиться к скобкам).
Пример.

select regexp_substr('TIPTOP4152', 'TOP(\d+)', 1, 1, NULL, 1) nbr
-- благодаря последнему параметру и скобкам, система возвращает то, что в скобках. Номер это какие скобки по очереди вернуть.
  from dual;  
nbr
4152

пример regexp_like

-- повторение любого символа строго более 5 раз подряд ( 6 и более )
select 1 as z 
  from dual
 where regexp_like(11121111555555, '(.).*\1{5}') 
select z.a 
  from (
        select '5-1' as a from dual union all
        select '555' as a from dual union all
        select 'a5a 1349853940589304' as a from dual union all
        select 'asdasd' as a from dual union all
        select '51 12 345678-' as a from dual union all
        select '51 ' as a from dual union all
        select '51 12 345678' as a from dual
  ) z
  where regexp_like(z.a, '[0-9]{6}') -- имеющие 6 цифр
    and regexp_like(z.a, '^[0-9]{2}') -- начинающиеся на как минимум две цифры

Пример с поискам значения внутри тэга

Если вам понадобилось найти в неструктурированном тексте число между двумя тегами не включая теги, то для этого в регулярных выражениях есть решение.
Оно называется lookbehind. В oracle к сожалению данная часть функционала регулярных выражений не поддерживается.
К счастью есть несколько решений позволяющих получить результат.
Повторюсь: задача получить число между тегами, не включая сам тег.

Пример: исходная строка: "243 mysupertag->42<-mysupersupertag" требуется получить: 42

Решение правильное:
Использовать функционал групп (capture group - т.е. скобки).
Работает это через дополнительный параметр в функции regexp_substr, называющийся subexpr, где мы указываем какая именно группа должна быть возвращена в качестве результата.

select regexp_substr('243 mysupertag->42<-mysupersupertag', 'mysupertag->(\d+)<-mysupersupertag', 1, 1, NULL, 1) as extracted_value
-- благодаря последнему параметру и скобкам, система возвращает то, что в скобках. Номер это какие скобки по очереди вернуть.
  from dual;
extracted_value
42

Решение грубое: Выбрать всё в т.ч. и теги, и заменить их помощью replace на пустоту (так лучше не делать).

select replace(
                replace(
                          regexp_substr('243 mysupertag->42<-mysupersupertag', 'mysupertag->(\d+)<-mysupersupertag', 1, 1, NULL, 1)
                          , 'mysupertag->', ''
                        )
                , '<-mysupersupertag', ''
              ) as extracted_value
    from dual;

На данное решение я натолкнулся благодаря ответу на SO: https://stackoverflow.com/questions/32359433/oracle-look-behind-positive

1.3 Регулярные выражения в emacs   emacs

В emacs есть много функционала работающего с регулярными выражениями.
В данной заметке мы рассмотрим наиболее интересные возможности.

В emacs в регулярных выражениях символы:

  • ( ) { } - надо экранировать, если это команда, а не символ.
  • * и . - должны быть экранированы если ищем символы * или ., а не команду.

C-M-s или M-x isearch-forward-regexp
Инкрементальный поиск вперед по регулярному выражению.

C-M-r или M-x isearch-backward-regexp
Инкрементальный поиск назад по регулярному выражению.

M-x replace-regexp
Заменить с помощью регулярного выражения.

C-M-% или M-x query-replace-regexp
Заменить с помощью регулярного выражения. Дополнительно спрашивает перед каждой заменой. Есть опция заменить всё.

Пример. Есть текст в виде таблицы с разделителями.
задача: добавить цифру 7 после шестого по счёту символа ;
1asd;2asd;3asd;4asd;5asd;;8asd
1asd;2asd;3asd;4asd;5asd;109283;8asd
1asd;2asd;3asd;4asd;5asd;;8asd
1asd;2asd;3asd;4asd;5asd;;8asd
1asd;2asd;3asd;4asd;5asd;;8asd

C-M-%
\(.*?;.*?;.*?;.*?;.*?;\)\(.*?\)\(.*?$\) → \17\3
тут вставляется первая скобка: \1, цифра 7 и \3 третья скобка
результат:
1asd;2asd;3asd;4asd;5asd;7;8asd
1asd;2asd;3asd;4asd;5asd;7109283;8asd
1asd;2asd;3asd;4asd;5asd;7;8asd
1asd;2asd;3asd;4asd;5asd;7;8asd
1asd;2asd;3asd;4asd;5asd;7;8asd

M-x align-regexp
Выровнять текст с помощью регулярного выражения.

исходные данные: 
tag1>    ; 42123; <tag1
tag1>   ; 1223423423; <tag1
tag1> ; 521; <tag1
tag1> ; 72; <tag1

выделяем текст и выполняем команду для выравнивания по символу ;
C-u M-x align-regexp
\(\s-*\);
1,1,y

результат:
tag1> ; 42123      ; <tag1
tag1> ; 1223423423 ; <tag1
tag1> ; 521        ; <tag1
tag1> ; 72         ; <tag1

Пример из документации. исходные данные:
Fred (123) 456-7890  (44) sdfsdf
Alice (123) 456-7890     (4423) sdfsdf
Mary-Anne (123) 456-7890 (44) sdfsdf
Joe (123) 456-7890     (44) sdfsdf

M-x align-regexp
\(\s-*\)(

Результат:
Fred      (123) 456-7890  (44) sdfsdf
Alice     (123) 456-7890     (4423) sdfsdf
Mary-Anne (123) 456-7890 (44) sdfsdf
Joe       (123) 456-7890     (44) sdfsdf

А если сделать команду:
C-u M-x align-regexp
\(\s-*\)(
1,1,y то получим применение выравнивания несколько раз:

Fred      (123) 456-7890 (44) sdfsdf
Alice     (123) 456-7890 (4423) sdfsdf
Mary-Anne (123) 456-7890 (44) sdfsdf
Joe       (123) 456-7890 (44) sdfsdf

почитать подробнее можно по ссылке: https://www.emacswiki.org/emacs/AlignCommands

M-s h r или M-x highlight-regexp
выделяет строки в буффере цветом. цвет указывается в параметрах.

M-s o или occur
Создаёт буффер, где показывает строки совпадающие с поисковым регулярным выражением.
Строки кликабельны. По клику осуществляется переход к найденной строке.

M-x keep-lines
удаляет все строки, кроме подходящих под регулярное выражение.

M-x flush-lines
удаляет все строки подходящие под регулярное выражение.

2 oracle   oracle

2.1 примеры partitioning

ctas and partitioning

Создавать партицированные таблицы можно и с помощью оператора create table as select. Пример приведен ниже.

create table ah_table 
  parallel 8 
  nologging 
  partition by range (report_date) interval (numtoyminterval(1, 'MONTH')) 
    (partition p0 values less than (to_date('2005-01-01', 'yyyy-mm-dd'))) 
    tablespace yourts as 
(
select  /*+parallel(8)*/  date'2020-01-01' report_date, 42 as kf_value union all
select  /*+parallel(8)*/  date'2020-02-01' report_date, 42 as kf_value 
)

create partition ddl range day patition and hash subpartition

Создание партицирования: range по дате и hash для субпартиций

create table tablename
(
  pk_hash        raw(20) not null,
  report_date    date not null,
  id             number  )
tablespace yourts
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  )
compress for all operations
nologging
partition by range (report_date) interval (numtodsinterval(1, 'DAY'))  -- partition by range (report_dt) interval (numtoyminterval(1, 'MONTH'))
subpartition by hash(id) 
  subpartitions 256
(
  partition p0 VALUES LESS THAN (to_DATE('2001-01-01', 'yyyy-mm-dd')),
  partition p1 VALUES LESS THAN (to_DATE('2001-02-01', 'yyyy-mm-dd'))
);

create partition ddl range number

Создание партиций: range по числовому значению

drop table tablename;
-- Create table
create table tablename
(
  num     NUMBER,
  secondf NUMBER
)
tablespace yourts
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  )
partition by range (num) interval(1)
(
  partition p0 values less than (1),
  partition p2 values less than (2)    
);

create partition ddl range by month and semi dynamic range

Создание партиций range по месяцу и набор фиксированных по number

create table tablename
(
  id              INTEGER,
  report_dt       DATE,
  metric_id       INTEGER,
  val_dc_lcl      NUMBER
)
tablespace yourts
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  )
partition by range (report_dt) interval (numtoyminterval(1, 'MONTH'))
  subpartition by range (metric_id) --interval(1)
  subpartition template

    ( 
     subpartition vld0 VALUES LESS THAN (1),
     subpartition vld5 VALUES LESS THAN (5),
     subpartition vld10 VALUES LESS THAN (10),
     subpartition vldm VALUES LESS THAN (maxvalue) )

  (partition p0 VALUES LESS THAN (to_DATE('2005-02-01', 'yyyy-mm-dd'))   
);  

create partition ddl range day interval week*

создание партиции по неделям

create table tablename
(
  ID              number(4, 0)
, creation_date   date
)
partition by range  (creation_date) interval ( numtodsinterval(7, 'day') )
  (partition TEST_P1 values less than (to_date(' 2018-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')));

create partition ddl hash

Создание партиций по hash с фиксированным количеством

create table tablename
(
  id                       NUMBER,
  c_date                   DATE
)
tablespace yourts
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  )
  partition by hash(id) partitions 1024
  ;

partitioning range date range metric

create table tablename
(
  id INTEGER,
  report_dt       DATE,
  metric_id       INTEGER,
  val_dc_lcl      NUMBER
)
tablespace yourts
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  )
partition by range (report_dt) interval (numtoyminterval(1, 'MONTH'))
  subpartition by range (metric_id) --interval(1)
  subpartition template 
    (
       subpartition  vld0 VALUES LESS THAN(10000),
       subpartition  vld1 VALUES LESS THAN(10001),
       subpartition  vld2 VALUES LESS THAN(10002),      
       subpartition vldm VALUES LESS THAN (maxvalue) 
     )     
  (partition p0 VALUES LESS THAN (to_DATE('2005-02-01', 'yyyy-mm-dd'))   
);

partitioning by range interval subpartition by range number

create table tablename
(
  tableley     NUMBER(20) not null,
  product_type NUMBER(1),
  update_ts          DATE
)
partition by range (update_ts) interval (numtodsinterval(1, 'DAY'))  -- partition by range (report_dt) interval (numtoyminterval(1, 'MONTH'))
  subpartition by range (PRODUCT_TYPE) 
  subpartition template 
  (
    subpartition pt1 values less than (2),
    subpartition pt2 values less than (3),
    subpartition pt3 values less than (4),
    subpartition pt4 values less than (5),
    subpartition ptm values less than (maxvalue)  
  )
  (partition p0 VALUES LESS THAN (to_date('2019-01-01', 'yyyy-mm-dd'))
  );

2.2 хинт statement_queuing

Если вы не хотите чтобы ваш запрос даунгрейдился, есть хинт STATEMENT_QUEUING. Неверное и необдуманное использование данного хинта, как и многих других черевато нехорошими последствиями

select /*+ parallel(8) statement_queuing */ *
  from dual
  where rownum < 5

2.3 sqlloader

тип TIMESTAMP для sqlloader ODS$VALIDFROM TIMESTAMP "YYYY-MM-DD HH24:MI:SS.FF6",

Чтобы загрузить в таблицу из csv

CREATE TABLE SCHEMA.TEST_TABLE (
  ID        NUMBER,
  VALUE     NUMBER,
  REPORT_DT DATE
)

Файл EXPORT.csv


542351;123;2019-01-01 123125;456;2019-01-02 346363;789;2019-01-03

ctl файл

Файл EXPORT.ctl
----------------------------------------------------------------------------------------------------------
OPTIONS (SKIP=0)
LOAD DATA
INFILE 'EXPORT.csv'
BADFILE 'EXPORT.bad'
DISCARDFILE 'EXPORT.dsc'
APPEND
INTO TABLE SCHEMA.TEST_TABLE
FIELDS TERMINATED BY ';'
TRAILING NULLCOLS
(
ID,
VALUE,
PEPORT_DT DATE "YYYY-MM-DD"
)

Файл EXPORT.bat (параметр кодировки chcp 1251 (Win) или 65001 (UTF8)…)

@echo off
chcp 65001
set NLS_NUMERIC_CHARACTERS=,.
sqlldr login/"pass"@yourservername:1521/yoursidname control=EXPORT.ctl direct=true parallel=true
pause

2.3.1 Загрузка блобов в oracle через sqlloader с локальной машины

@echo off
chcp 65001
set NLS_NUMERIC_CHARACTERS=,.
sqlldr asriyan_av/"passhere!!!"@yourservervname:1521/yoursid control=EXPORT.ctl direct=true parallel=false
pause

csv для загрузки. Во втором поле храним путь к файлу для загрузки в колонку.

1;D:\eav\sqlload\eav.rar;

ctl

OPTIONS (SKIP=0)
LOAD DATA
INFILE 'EXPORT.csv'
BADFILE 'EXPORT.bad'
DISCARDFILE 'EXPORT.dsc'
APPEND
INTO TABLE ASRIYAN_AV.TEST_BLOB
FIELDS TERMINATED BY ';'
TRAILING NULLCOLS
(
ID,
FNM FILLER,
VALUE LOBFILE(FNM) TERMINATED BY EOF
)

table DDL where we want to load data

CREATE TABLE "ASRIYAN_AV"."TEST_BLOB" 
 (      "ID" NUMBER, 
      "FNM" NVARCHAR2(100), 
      "VALUE" BLOB
 ) ;

2.4 meta query

2.4.1 get tablespace size

select /*+ parallel(1)*/ 
       a.tablespace_name,
       round(a.used_space*8192/1024/1024/1024/1024,2) as used_space_tb,
       round(a.tablespace_size*8192/1024/1024/1024/1024,2)  tablespace_size_tb,
       round(a.used_percent,2) used_percent,
       round(a.tablespace_size*8192/1024/1024/1024/1024,2) - round(a.used_space*8192/1024/1024/1024/1024,2) as free_size_tb
  from dba_tablespace_usage_metrics a;

2.4.2 get plan

sql_id and sql_exec_id you can find in v$session

get plan

select dbms_sqltune.report_sql_monitor( sql_id => '0h8fg425sz9n6',
                                        sql_exec_id => 16777216,
                                        type => 'TEXT' )  -- ACTIVE -- TEXT -- HTML
  from dual;

2.4.3 table statistics

посчитать статистику для таблицы

begin
  dbms_stats.gather_table_stats( 'TABLESCHEMA', 'TABLENAME', degree => 8, cascade => true );
end;

2.4.4 create table with dates

select add_months(DATE'2018-01-31',rownum) as crazy_month 
  from dual 
  connect by rownum < 100;
select last_day(to_date('2018-01-01', 'yyyy-mm-dd') + rownum - 1) as crazyday
  from all_objects 
 where rownum <= to_date('2018-12-01','yyyy-mm-dd')- to_date('2018-01-01', 'yyyy-mm-dd') + 1
 group by last_day(to_date('2018-01-01', 'yyyy-mm-dd') + rownum - 1)

2.4.5 delta oracle SCN

select current_scn from v$database; -- get current scn number
select a.ora_rowscn, a.* from schemaname.tablename a; -- from table
select timestamp_to_scn(sysdate) from dual;
select dbms_flashback.get_system_change_number from dual;
select scn_to_timestamp(ora_rowscn) from schemaname.tablename

2.4.6 oracle generate random number in range

select round(dbms_random.value(1,10000000),0) as zzz 
from dual

2.4.7 create table into dblink

declare 
 --vv varchar2(32000);
 --zz clob;
begin  
  dbms_utility.exec_ddl_statement@dbnlinkname('CREATE TABLE ZZZ1 (id number)');
  -- dbms_utility.exec_ddl_statement@score_rp('CREATE TABLE ZZZ1 AS SELECT 1 AS VV FROM DUAL');
  dbms_utility.exec_ddl_statement@dblinkname('DROP TABLE ZZZ1');
end;
/*
   select dbms_metadata.get_ddl('TABLE','TEST_SCH','ASRIYAN_AV')
      into zz
    from dual;
  vv := dbms_lob.substr(zz,32000);      
  dbms_output.put_line(vv); 
*/  

2.4.8 create error table

BEGIN
  dbms_errlog.create_error_log('TABLENAME', 'ERR_TABLENAME'); -- ERR_TABLENAME will be created
END;
/
MERGE tablename
LOG ERRORS INTO schemaname.err_tablename('L_TABLENAME') REJECT LIMIT 10000; -- additional label for error        

2.4.9 regexp_substr connect by

select  regexp_substr('Петров,1111111,Москва','[^,]+',1,level) ll
       from dual
     connect by level <=  REGEXP_COUNT('Петров,1111111,Москва',',')+1
select
    standard_hash(1, 'SHA1') as PK -- sys_guid() 
   , regexp_replace('12312  3A Я z', '[A-Za-zА-Яа-я\ ]','')         
   , regexp_replace('12312  3A Я z', '^[0-9]','')         
   , regexp_replace('12312  3A Я z', '[^0-9]','')         
   , regexp_replace('12312  3A Я z', '[^[:digit:]]','')         
   , sysdate as create_date 
 from dual a

2.4.10 Зависимости от объекта oracle

SELECT     TO_CHAR (d.object_id) object_id,
           TO_CHAR (referenced_object_id) referenced_object_id,
           TO_CHAR (LEVEL) "LEVEL",
           o.*           
      FROM public_dependency d
        LEFT JOIN dba_objects o on o.object_id = d.object_id
CONNECT BY PRIOR d.object_id = referenced_object_id
START WITH referenced_object_id =
              (
               SELECT object_id --* --object_id
                 FROM SYS.dba_objects
                WHERE owner = 'SCHEMA_NAME'
                  AND object_name = 'OBJECT_NAME'
                  AND object_type = 'PROCEDURE' -- TABLE
               )

2.4.11 Undo space usage by transactions

–Undo space usage by transactions

/*set lines 200
col username format a10 wrapped heading "User"
col name format a22 wrapped heading "Undo Segment Name"
col xidusn heading "Undo|Seg #"
col xidslot heading "Undo|Slot #"
col xidsqn heading "Undo|Seq #"
col ubafil heading "File #"
col ubablk heading "Block #"
col start_time format a10 word_wrapped heading "Started"
col status format a8 heading "Status"
col blk format 999,999,999 heading "KBytes"
col used_urec heading "Rows"
alter session set nls_date_format='dd.mm.yyyy hh24:mi:ss'; */
SELECT S.SID, t.START_TIME, s.USERNAME, R.NAME "Rollback segment name",  
ubafil, ubablk, t.status "Transaction status", s.status "Session status", (used_ublk*p.value)/1024/1024 "Undo, Mbytes", used_urec, s.sql_id, p1.spid "OS pid"
FROM V$TRANSACTION T, V$ROLLNAME R, V$SESSION S, V$PARAMETER P, v$process p1
where t.xidusn=r.usn
and s.saddr=t.ses_addr
and s.paddr=p1.addr(+)
AND P.NAME='db_block_size'
order by "Undo, Mbytes" desc;

2.4.12 parallel dml enable hint

enable_parallel_dml parallel(8)

2.4.13 Oracle get plan 2 and other good tables

select * from v$sql_monitor –v$sql_plan_monitor select * from gv$sql select * from gv$sql_monitor select * from v$sql_plan_monitor select * from gv$active_session_history

select * from v$sql_monitor –v$sql_plan_monitor –select * from gv$sql select * from gv$active_session_history

select dbms_sqltune.report_sql_detail(sql_id => 'btsnqn6jh6gm5', type => 'TEXT', report_level => 'ALL') from dual;
select dbms_sqltune.report_sql_monitor_list( type => 'HTML', report_level => 'ALL' ) as report from dual;
select dbms_sqltune.report_sql_monitor_list(type => 'TEXT', report_level => 'ALL') from dual;

2.4.14 oracle sql get hour from timestamp

select extract(hour from systimestamp)+3 from dual;

2.4.15 SQL plan monitor oracle

yet another sql to find history of queries

select /*+ parallel(1) */
    s.sql_id 
   ,s.sql_text 
   ,s.parsing_schema_name as account -- account 
   ,round(s.rows_processed / 1000000, 2) as rows_m -- rows processed millions
   ,s.executions as execs 
   ,round(s.elapsed_time / 1000000 / 60, 0) as time -- elapsed_time_sec - min
   ,round(s.cpu_time / 1000000 / 60 ,0) as cpu_time -- cpu_time_sec - min
   ,round(s.concurrency_wait_time / 1000000,0)  as conc -- concurrency 
   ,round(s.disk_reads/1000000,2) as disk_r -- hz why / 1000000
   ,round(s.direct_writes/1000000,2) as disk_w -- hz why / 1000000
   ,s.last_active_time  
  from v$sql s 
 where s.last_active_time >= date'2019-07-12'
   and s.rows_processed > 0
   and round(s.elapsed_time / 1000000, 0) > 1
   --and s.sql_id = 'cz7gbur20btuc'   
   order by s.elapsed_time desc
--SQL Plan Monitor
select status,
       output_rows,
       plan_line_id,
       lpad('  ', 2*plan_depth-1) || plan_operation operation,
       plan_options,
       plan_object_name,
       plan_object_type,
       plan_cost,
       plan_cardinality
       plan_bytes,
       plan_time,
       plan_partition_start,
       plan_partition_stop,
       plan_cpu_cost,
       plan_io_cost,
       plan_temp_space,
       starts,
       io_interconnect_bytes,
       physical_read_requests,
       physical_read_bytes,
       physical_write_requests,
       physical_write_bytes,
       workarea_mem,
       workarea_max_mem,
       workarea_tempseg,
       workarea_max_tempseg,
       numtodsinterval(last_refresh_time - first_refresh_time, 'day') as elaps
from   (
        select v$sql_plan_monitor.*
        from   v$sql_plan_monitor, v$sql_plan
        where  v$sql_plan.address = hextoraw(:sql_address) and
               v$sql_plan.hash_value = :sql_hash_value and
               v$sql_plan.sql_id = v$sql_plan_monitor.sql_id and
               v$sql_plan_monitor.sql_exec_id = :sql_exec_id and
               v$sql_plan.child_address = v$sql_plan_monitor.sql_child_address and
               v$sql_plan.plan_hash_value = v$sql_plan_monitor.sql_plan_hash_value and
               v$sql_plan.id = v$sql_plan_monitor.plan_line_id
       )

order by plan_line_id, plan_position

2.4.16 oracle paralell hint

alter session force parallel query parallel 1;

2.4.17 hier query to get dates

WITH gen_dates ( dt ) AS -- generate dates
  ( 
    SELECT date'2018-01-01' AS dt     
      FROM dual
    UNION ALL
    SELECT   r.dt + 1 AS i           
      FROM gen_dates r 
     WHERE dt < sysdate     
  )
SELECT * FROM gen_dates;  
SELECT date'2018-01-01' + rownum AS vv 
  FROM dual 
  CONNECT BY date'2018-01-01' + rownum < sysdate

2.4.18 get oracle database name

select name from v$database

2.4.19 get non auditable tables

select a.owner, a.table_name
  FROM all_tables a -- table where you have grant. also you can see USER_TABLES or DBA_TABLES
    left join DBA_OBJ_AUDIT_OPTS b on a.owner = b.owner AND a.table_name = b.object_name 
 where a.tablespace_name = 'SCHEMANAME'
   and b.object_name is null

2.4.20 get job ddl

Получить DDL создания джоба из базы запросом

SELECT /*+ parallel(1)*/ dbms_metadata.get_ddl(object_type => 'PROCOBJ', name => 'PROCNAME', SCHEMA => 'SCHEMANAME') FROM dual;
SELECT /*+ parallel(1)*/ dbms_metadata.get_ddl(object_type => 'TABLE', name => 'TABLENAME', SCHEMA => 'SCHEMANAME') FROM dual;
select dbms_metadata.get_dependent_ddl('OBJECT_GRANT', 'TABLENAME', 'SCHEMANAME') from dual;

2.4.21 dbms_rls get fields

get list of fields with RLS!

SELECT * FROM ALL_SEC_RELEVANT_COLS

2.4.22 dyn_exec и кавычки.

С этим кодом вам не придется кавычки предварять escape символом

begin
  yourschema.yourprocname(iv_query=> q'[  
  select count('1') from dual 
  ]');
end;

2.4.23 select from list oracle

SELECT * FROM table(sys.odcinumberlist(1,2,3 ))

2.4.24 regex and with function   regex

WITH tr_datas AS ( SELECT '12-Mar-20' val FROM dual UNION all
                   SELECT '11-Jul-20' FROM dual UNION ALL
                   SELECT '11-Jul-bad20' FROM dual UNION ALL
                   SELECT '11-Jul-20 0000 AM' FROM dual UNION ALL
                   SELECT 'bad11-Jul-bad20' FROM dual 
                 )
SELECT val, 
       regexp_substr(val,'^([0-9]){2,2}-([a-zA-Z]){3,3}-([0-9]){2}'),
       to_char(to_date(upper(regexp_substr(val,'^([0-9]){2,2}-([a-zA-Z]){3,3}-([0-9]){2}')), 'DD-MON-YY', 'NLS_DATE_LANGUAGE=AMERICAN'),'dd.mm.yyyy') AS converted_date
  FROM tr_datas
 WHERE regexp_like(val, '^([0-9]){2,2}-([a-zA-Z]){3,3}-([0-9]){2}')

with function 
QQ(dd varchar2,ff varchar2) return  varchar2 deterministic
as
  v_date date;
begin
  select to_date(dd, ff) into v_date from dual;
  return  'Y' ;
  exception when others then return 'N';
end ;
SELECT 
 qq('01-01-2019','DD-MM-YYYY') F_CHECK1
,qq('91-01-2019','DD-MM-YYYY') F_CHECK2
FROM DUAL

3 postgres   postgres

3.1 установка postgres из исходников

краткая версия для сборки postgres 13:

перед началом сборки устанавливаем необходимые пакеты:

  • zlib : libzlib1g-dev
  • readline : libreadline-dev
  • gcc
  • make

скачиваем исходный код нужно версии postgres отсюда и распаковываем.

./configure
make
su
make install
adduser postgres
mkdir /usr/local/pgsql/data
chown postgres /usr/local/pgsql/data
su - postgres
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start
/usr/local/pgsql/bin/createdb test
/usr/local/pgsql/bin/psql test

вместо /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data можно использовать pg_ctl -D /usr/local/pgsql/data initdb pg_ctl -D /usr/local/pgsql/data start

contrib не будет сгенерирован. для него надо запускать make вот так: make world

для установки в другой каталог, например для обновления. нужно использовать опцию make install prefix=/usr/local/pgsql2/

настройка PATH: ~/.bashrc PATH=/usr/local/pgsql/bin:$PATH export PATH

3.2 запуск postges после сборки из исходников

запуск вручную. благодаря pg_ctl - оно запускается в фоновом режиме.

/usr/local/pgsql/bin/pg_ctl start -D /usr/local/pgsql/data -l /usr/local/pgsql/data/serverlog

пример systemd для запуска postgres из документации от 13 версии. для type=notify сервер должен быть сконфиругирован при сборке с флагом configure –with-systemd /etc/systemd/system/postgresl.service

[Unit]
Description= PostgreSQL database server
Documentation=man:postgres(1)

[Service]
Type=notify
User=postgres
ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
TImeoutSec=0

[Install]
WantedBy=multi-user.target

по дефолту папка с данными считывается из параметра запуска БД pg_ctl -D pathtodatadir. там же лежит postgresql.conf. в нём можно изменить следующие параметры: data_directory, hba_file, ident_file

3.3 pgbench утилита для тестирования нагрузки

  • i : инициализировать
  • s : scale. при значении 100 будет сгененировано 10 000 000 строк.

сгенерировать 10 млн записей в тестовых данных

pgbench -i -s 100

протестировать

  • t : количество транзакций на клиента
  • c : количество клиентов. запускаются параллельно
pgbench -t 1000 -c 100

есть ещё параметры скриптов:

3.4 generate random uuid

для генерации гуида начиная с 13 версии постгреса можно использовать функцию:

select gen_random_uuid()
gen_random_uuid
bd47d88c-4450-489e-b0ab-46c3dead415d

3.5 backup restore

есть варианты: pg_dump, pg_basebackup

базовую резервную копию можно получиться с помощью pg_basebackup пример: usr/local/pgsql/bin/pg_basebackup -D /myarchive второй пример с необязательными параметрами:

  • P отображать прогресс
  • s период в секундах - по умолчанию 10 секунд

usr/local/pgsql/bin/pg_basebackup -P -s 1 -D /myarchive

для восстановления останавливаем сервер. удаляем всё, что есть в каталоге с данными. и копируем из архива. запускаем сервер. при запуске он запускает рекавери. и быстренько восстанавливается. Если у нас есть какие-то заморочки с тейблспейсами или местом где лежат параметры - то надо геморроиться. см: https://www.percona.com/blog/2018/12/21/backup-restore-postgresql-cluster-multiple-tablespaces-using-pg_basebackup/

3.6 настройка репликации

физическая реплика. оно же постоянное архивирование и проигрывание wal. ограничение - только кластер целиком. т.е. все базы данных в нём.

для включения point-in-time recovery

3.6.1 асинхронная репликация близкая к реал тайму

в postgresql.conf задаём параметры:

wal_level = replica # (или выше)
listen_adresses = '*' # или указываем конкретный. это нужно для того чтобы пользователь через которого будет идти репликация мог подключиться с удаленного хоста (stand by реплики)
hot_standby = on

необязательные шаги: создание пользователя для репликациии:

create user replicator replication;

и добавляем в pg_hba.conf чтобы пользователь мог подключиться (ип указан для слейва)

host    test    replicator      192.168.122.141/32      trust

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

pg_basebackup -D /myarchive/ -U replicator -P -v -R -X stream -C -S pgstandby1

такой бекап создает пустой файл standby.signal в каталоге бекапа благодаря опции -R. этот файл означает что это реплика.

также создаётся файл postgresql.auto.conf. в нем хранится информация как подключаться к мастеру.

primary_conninfo = 'user=replicator passfile=''/var/lib/postgresql/.pgpass'' channel_binding=disable host=192.168.122.139 port=5432 sslmode=disable sslcomp\
ression=0 ssl_min_protocol_version=TLSv1.2 gssencmode=disable krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'pgstandby1'

важные параметры: user, host, port, primary_slot_name

копируем директорию с бекапом от pg_basebackup на сервер реплики:

scp -r postgres@192.168.122.139:/myarchive/* /usr/local/pgsql/data/

и запускаем как обычно от имени postgres: pg_ctl -D /usr/local/pgsql/data start -l /usr/local/pgsqll/data/logfile смотрим логи на предмет того что постгрес смог подключиться к мастеру для забора логов. tail /usr/local/pgsqll/data/logfile

для удаления слота репликации:

select pg_drop_replication_slot('pgstandby1');

3.6.2 репликация через архивирование логов

в postgresql.conf задаём параметры:

wal_level = replica # (или выше)
listen_adresses = '*' # или указываем конкретный. это нужно для того чтобы пользователь через которого будет идти репликация мог подключиться с удаленного хоста (stand by реплики)
hot_standby = on
archive_mode = on
archive_command = 'test ! -f /mywallarchive/%f && cp %p /mywallarchive/%f'
restore_command = 'scp postgres@192.168.122.139:/mywallarchive/%f "%p"'

archive_command = тут команда по архивированию логов. %p (путь к файлу). %f (имя файла). пример команды ниже. путь задаётся относительно рабочего каталога БД. archive_command = 'test ! -f /myarchive/%f && cp %p /myarchive/%f' restore_command = 'cp /myarchive/%f "%p"'

архивация логов происходит только при заполнении лога. если записи в системе нет - данные попадут могут попасть на реплику с неопределенной задержкой. чтобы этого избежать можно в postgresql.conf установить таймаут на принудительную смену файла. файлы будут весить 16 мегабайт даже если там пусто. archive_timeout = 60 # в секундах

принудительно заархивировать wal можно с помощью команды:

postgres=# select pg_switch_wal();

снимаем бекап через pg_basebackup

pg_basebackup -D /myarchive/ -P

опция -R в pg_basebackup создаёт пустой файл standby.signal в директории бекапа. однако он же создает параметры подключения в postgresql.auto.conf. эти параметры postgresql.auto.conf - делают так, что запускается потоковая репликация. если их убрать, а именно primary_conninfo - то запустится воспроизведение wal.

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

  • recovery.signal - в этом случае после восстановления - система превратиться в мастер систмему
  • standby.signal - в этом случае система будет оставаться в режиме восстановления выполняя команду restore_command.

в нашем случае - создаем пустой файл standby.signal в директории базы данных реплики.

touch /usr/local/pgsql/data/standby.signal

чтобы очищать ненужные для реплики файлы есть команда:

archive_cleanup_command = 'pg_archivecleanup -d /mywallarchive %r'

её надо запускать на реплике (т.к. только она знает какой файл уже обработан). в моём примере архив журналов хранится на мастере поэтому пример не рабочий. команда pg_archivecleanup удаляет все файлы до указанного в параметре.

3.6.3 логическая репликация

wal_level = logical
create table zzz (guid uuid primary key, num numeric, txt text);

create publication mypub for table zzz;
create table zzz (guid uuid primary key, num numeric, txt text);

create subscription mysub connection 'dbname=test host=192.168.122.139 user=postgres' publication mypub;

готово. при условии что postgres может подключаться без пароля. использование другой учётки привело к нерабочему функционалу:

цитата из src: https://habr.com/ru/company/postgrespro/blog/489308/ "Обратите внимание что, несмотря на то что логическая репликация основана в значительной мере на потоковой, указывается не специальная запись replication, а имя базы или all — указание на все базы. Если указать replication, то создать подписку на реплике не получится из-за ошибки аутентификации."

3.7 обновление версии postgres

обновление БД. бывает минорное и мажорное обновление. если минорное - то там бинарная совместимость на уровне файлов. по идее надо просто собрать новые бинарники и запустить. если обновляем мажорную версию, наприме с 13 на 14 версию - тогда нужно делать так:

  • собираем исходники в другую папку (make prefix=/usr/local/pgsql.new/ install)
  • делаем инит с совместимыми параметрами
  • останавливаем старую БД
  • поднимаем wal_level - до уровня выше minimal для нового сервера. + делаем настройки авторизации
  • запускаем pg_upgrade от нового сервера. pg_upgrade –old-datadir "usr/local/pgsql/data" –new-datadir "usr/local/pgsql2/data" –old-bindir "usrl/local/pgsql/bin" –new-bindir "usr/local/pgsql2/bin". если хотим не копировать файлы нужно указать флаг -k (создать симлинки).
  • иногда pg_upgrade выдаёт скрипт который надо запустить после обновления
  • посчитать статистику на новом сервере

по умолчанию pg_upgrade делает копию файлов базы данных. с флагом -k - создаются симлинки (работает только если новый кластер на той же самой файловой системе).

4 emacs   emacs

4.1 .emacs мой конфиг

.emacs

(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3") ;; to fix problem with melpa

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)

(package-initialize)

(load "~/.emacs.d/zmycustom.el")


(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(custom-enabled-themes '(nord))
 '(custom-safe-themes
   '("37768a79b479684b0756dec7c0fc7652082910c37d8863c35b702db3f16000f8" default))
 '(inhibit-startup-screen t)
 '(org-agenda-custom-commands
   '(("g" . "GTD command")
     ("gp" "project" tags-todo "+project -maybe" nil)
     ("gn" "next" tags-todo "next" nil)
     ("gi" "inbox" tags-todo "inbox" nil)
     ("gr" "agenda GTD reminder" agenda "calendar reminder"
      ((org-agenda-tag-filter-preset
        '("+reminder"))))
     ("gw" "agenda GTD waiting" agenda "calendar waiting"
      ((org-agenda-tag-filter-preset
        '("+waiting"))))
     ("gc" "agenda GTD calendar" agenda "calendar"
      ((org-agenda-tag-filter-preset
        '("+calendar"))))
     ("gl" "maybe later" tags-todo "maybe" nil)))
 '(org-agenda-files '("~/all/org/home.org"))
 '(org-tags-exclude-from-inheritance '("info" "movie" "book" "read" "next" "project"))
 '(package-selected-packages
   '(realgud htmlize ox-hugo go-mode cider visual-regexp slime undo-tree nord-theme which-key region-bindings-mode multiple-cursors helm-projectile elpy))
 '(tool-bar-mode nil))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )

.emacs.d/zmycustom.el

;; packages to install:
;; multiple-cursors region-bindings-mode elpy projectile helm-projectile which-key undo-tree nord-theme visual-regexp

;; auto install packages ++
(defvar my-packages
  '(multiple-cursors region-bindings-mode elpy projectile helm-projectile which-key undo-tree nord-theme visual-regexp realgud htmlize))

;; realgud

(mapc #'(lambda (package)
          (unless (package-installed-p package)
            (package-install package)))
      my-packages)
;; auto install packages --

(require 'multiple-cursors)

(global-set-key (kbd "C->") 'mc/mark-next-like-this)
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
(global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)  
(global-unset-key (kbd "M-<down-mouse-1>"))
(global-set-key (kbd "M-<mouse-1>") 'mc/add-cursor-on-click)
(global-set-key (kbd "C-c m") 'mc/mark-all-in-region)
;; or you can you C-SHIFT left mouse click
;; (global-set-key (kbd "C-S-<mouse-1>") 'mc/add-cursor-on-click)
;; after that you can use multiplie cursor with ALT and left mouse click
;; with multiplie-cursors you need to use package region-bindings-mode. you can install it from melpa
(require 'region-bindings-mode)
(region-bindings-mode-enable)

(define-key region-bindings-mode-map "g" 'keyboard-quit)
(define-key region-bindings-mode-map "a" 'mc/mark-all-like-this)
(define-key region-bindings-mode-map "p" 'mc/mark-previous-like-this)
(define-key region-bindings-mode-map "n" 'mc/mark-next-like-this)
(define-key region-bindings-mode-map "m" 'mc/mark-more-like-this-extended)
(define-key region-bindings-mode-map "P" 'mc/unmark-previous-like-this)
(define-key region-bindings-mode-map "N" 'mc/unmark-next-like-this)
(define-key region-bindings-mode-map "[" 'mc/cycle-backward)
(define-key region-bindings-mode-map "]" 'mc/cycle-forward)
(define-key region-bindings-mode-map "h" 'mc-hide-unmatched-lines-mode)
(define-key region-bindings-mode-map "\\" 'mc/vertical-align-with-space)
(define-key region-bindings-mode-map "#" 'mc/insert-numbers) ; use num prefix to set the starting number
(define-key region-bindings-mode-map "^" 'mc/edit-beginnings-of-lines)
(define-key region-bindings-mode-map "$" 'mc/edit-ends-of-lines)
(define-key region-bindings-mode-map "r" 'mc/mark-all-in-region-regexp)

(setq inferior-lisp-program "sbcl --dynamic-space-size 8192") 

;;(elpy-enable)

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t)
   (python . t)
   (shell . t)
   (sql . t)
   (dot . t)
   (gnuplot . t)    
   (ditaa . t)   
   (lisp . t)))

(setq org-babel-python-command "/usr/bin/python3")

(setq org-confirm-babel-evaluate nil)

(projectile-mode +1)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)

(require 'helm-projectile)
(helm-projectile-on)

(global-set-key (kbd "M-x") 'helm-M-x)
(global-set-key (kbd "C-x C-f") #'helm-find-files)
(global-set-key (kbd "C-x r b") #'helm-filtered-bookmarks)

(helm-mode 1)


(put 'downcase-region 'disabled nil)
(put 'narrow-to-region 'disabled nil)

(require 'info)

(require 'which-key)

(which-key-mode)

(global-set-key (kbd "C-x w") 'elfeed)
(global-set-key (kbd "C-c g") 'grep)

(elpy-enable)

(which-key-setup-side-window-right)

(windmove-default-keybindings)  

;;(custom-set-variables
;; ;; custom-set-variables was added by Custom.
;; ;; If you edit it by hand, you could mess it up, so be careful.
;; ;; Your init file should contain only one such instance.
;; ;; If there is more than one, they won't work right.
;; '(custom-enabled-themes '(nord))
;; '(custom-safe-themes
;;   '("37768a79b479684b0756dec7c0fc7652082910c37d8863c35b702db3f16000f8" default))
;; '(org-agenda-custom-commands
;;   '(("g" . "GTD command")
;;     ("gp" "project" tags-todo "+project -maybe" nil)
;;     ("gn" "next" tags-todo "next" nil)
;;     ("gi" "inbox" tags-todo "inbox" nil)
;;     ("gr" "agenda GTD reminder" agenda "calendar reminder"
;;      ((org-agenda-tag-filter-preset
;;      '("+reminder"))))
;;     ("gw" "agenda GTD waiting" agenda "calendar waiting"
;;      ((org-agenda-tag-filter-preset
;;      '("+waiting"))))
;;     ("gc" "agenda GTD calendar" agenda "calendar"
;;      ((org-agenda-tag-filter-preset
;;      '("+calendar"))))
;;     ("gl" "maybe later" tags-todo "maybe" nil)))
;; '(org-agenda-files '("~/all/org/home.org"))
;; '(org-tags-exclude-from-inheritance '("info" "movie" "book" "read" "next" "project"))
;; '(package-selected-packages
;;   '(nord-theme which-key region-bindings-mode multiple-cursors helm-projectile elpy))
;; '(tool-bar-mode nil))
;;(custom-set-faces
;; ;; custom-set-faces was added by Custom.
;; ;; If you edit it by hand, you could mess it up, so be careful.
;; ;; Your init file should contain only one such instance.
;; ;; If there is more than one, they won't work right.
;; )

(global-set-key (kbd "C-c a") #'org-agenda)

(global-undo-tree-mode 1)

(global-set-key (kbd "C-z") 'undo)
(defalias 'redo 'undo-tree-redo)
(global-set-key (kbd "C-S-z") 'redo)

(require 'visual-regexp)
(define-key global-map (kbd "C-c r") 'vr/replace)
(define-key global-map (kbd "C-c q") 'vr/query-replace)
;; if you use multiple-cursors, this is for you:
(define-key global-map (kbd "C-c m") 'vr/mc-mark)


(setq-default indent-tabs-mode nil)

(require 'ox-publish)

(defvar my-postamble
"<p> <br> [
<a href=\"/index.xml\">RSS</a> |
<a href=\"https://t.me/asriyanarthur\">Telegram</a> |
<a href=\"https://mastodon.ml/@asriyanarthur\"> Mastodon</a> |
<a href=\"https://github.com/asriyanarthur\">GitHub</a> |
<a href=\"mailto:arthur@asriyan.ru\">mail</a> |
<a href=\"https://asriyan.ru/\">главная</a> |
<a href=\"https://asriyan.ru/contact.html\">резюме</a>
]</p>
 <br>
 "
)


(load "~/.emacs.d/ox-rss-master/ox-rss.el")
(require 'ox-rss)

(setq org-publish-project-alist
      `(("org"
         :base-directory "~/all/projects/asriyanru/org/"
         :recursive t
         :base-extension "org"
         :publishing-directory "~/all/projects/asriyanru/public/"
         :publishing-function org-html-publish-to-html
         :auto-preamble t
         :auto-sitemap t         
         ;;:html-preamble ,my-preamble
         :html-postamble ,my-postamble
         )
        ("css"
         :base-directory "~/all/projects/asriyanru/css/"
         :recursive t
         :base-extension "css\\|js"
         :publishing-directory "~/all/projects/asriyanru/public/css/"
         :publishing-function org-publish-attachment)
        ("static"
         :base-directory "~/all/projects/asriyanru/static/"
         :recursive t
         :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf"
         :publishing-directory "~/all/projects/asriyanru/public/static/"
         :publishing-function org-publish-attachment)
        ("rss"
         :base-directory "~/all/projects/asriyanru/org/"
         :base-extension "org"
         :publishing-directory "~/all/projects/asriyanru/public/"
         :publishing-function (org-rss-publish-to-rss)
         ;;   :rss-image-url "http://pathtopng.png"
         ;;   :html-link-use-abs-url t
         :html-link-home "http://asriyan.ru/"
         :exclude ".*"            ;; To exclude all files...
         :include ("index.org")   ;; ... except index.org.   
         :html-link-use-abs-url t
         :rss-extension "xml")
        ("website" :components ("org" "css" "static" "rss"))))  

5 common lisp   commonlisp

Здесь обязательно что-то будет.

6 linux   linux

6.1 ssh config

Файл в котором хранятся настройки для подключения. ~/.ssh/config

Если в файле указано как в примере, то мы можем написать: ssh xxx и это будет означать: ssh root@1.1.1.1 + опция keepalive и подстановка ключа.

Host xxx ## name for ssh xxx
     Hostname 1.1.1.1 ## ip to connect
     User root ## remote user
     port 22 ## remote portt
     IdentityFile /home/youruser/.ssh/key.ppk ## may be ppk or other (private key)
     ServerAliveInterval 60 

6.2 ssh agent

eval `ssh-agent`
ssh-add pathtokey

in other terminal session you can find this data (ls /tmp/ssh* and ps aux | grep agent) ant put into new session SSH_AUTH_SOCK=/tmp/ssh-XXt4pHNr/agent.5087; export SSH_AUTH_SOCK; SSH_AGENT_PID=5088; export SSH_AGENT_PID; echo Agent pid 5088;

7 andorid   android

7.1 organic maps

Оффлайн карты, уважающие вашу приватность. Установить можно с PlayMarket или F-Droid.

Преимущества:

  • оффлайн режим работы
  • маленький размер карт
  • быстрая прокладка маршрутов
  • полное отсутствие трекеров

source: https://organicmaps.app/

7.2 street complete

приложение помогающее контрибьютить в openstreetmaps. сделано очень качественно.

source: https://f-droid.org/ru/packages/de.westnordost.streetcomplete/

7.3 syncthing-fork

Приложение для синхронизации файлов между устройствами.

source: https://f-droid.org/ru/packages/com.github.catfriend1.syncthingandroid/

7.4 k9-mail

почтовый клиент

source: https://f-droid.org/ru/packages/com.fsck.k9/

7.5 document viewer

Читалка для разных форматов. PDF, DjVu, XPS, CBZ, fb2, epub. Лучше всего на мой взгляд подходит для PDF.

source: https://f-droid.org/ru/packages/org.sufficientlysecure.viewer/

8 Почитать   read

Здесь будут сайты и книги к прочтению.

  • https://karl-voit.at/
    Блог интересного человека.
    Пишет про emacs, про ведение собственной базы знаний.
    Можно подписаться через rss.
  • https://systemcrafters.cc
    Популяризатор emacs/eslisp/orgmode/guix.
    есть также канал на youtube.


[ RSS | Telegram | Mastodon | GitHub | mail | главная | резюме ]