Computing 2017년 01월 17일의 Onggi. 2017/01/17 00:12 by WSID

안녕하세요~! 일요일에 써서 올렸어야 했지만, 이러쿵 저러쿵 하다보니 오늘 글을 써서 올리게 되었습니다. (...)

  1. 이름 덧붙이기


같은 이름의 테이블이 생성되는 것을 막기 위해 덧댄 이름을 사용하곤 합니다. 기존에는 수동으로 이름을 덧대어 썼지만, 지금은 자동으로 이름을 덧대어 쓸 수 있도록 하였습니다.



2. CREATE 속성 지정

테이블의 생성에 있어서는 다양한 특성이 적용됩니다. 어떤 특성은 크게 신경쓸 부분이 없어서 넘어갈 수 있지만, 어떤 특성의 경우는 성능등에 크게 영향을 미칠 수도 있습니다.

libgda는 테이블 생성을 비롯하여, 다양한 부분에서 세부적인 특성을 GdaServerOperation을 통해 조절할 수 있도록 하였습니다. 저는 이런 특성을 생성시에 GdaServerOperation에 전달할 수 있도록 함수를 추가하였습니다.

void onggi_module_object_set_create_attr (OnggiModuleObject *object,
    const gchar *attr,
    const gchar *value)

void onggi_module_object_set_create_attr_f (OnggiModuleObject *object,
    const gchar *attr,
    const gchar *value,
    ...)



3. [진행중] OnggiConstruction

OnggiModule을 직접 조립하여 (직접 OnggiTable, OnggiColumn을 생성하여 합치는 방법) 생성할 수 있습니다. 그러나 GUI가 직접 조립에서 데이터를 이용한 생성으로 건너간 것처럼, OnggiModule도 XML등을 이용해서 조립하도록 하였습니다.

전에서도 이야기 한 바와 같이, 이러한 기능을 뒷받침하는 것은 OnggiConstruction입니다. OnggiConstruction은 노드들을 트리 모양으로 구성하여 한꺼번에 객체들을 생성할 수 있도록 합니다. XML에서 객체를 생성해야 한다면, XML의 각 태그를 OnggiConstructionNode로 변환한 뒤, 이를 통해 객체를 생성하는 방식입니다.

기존의 구성 방식은 객체의 속성치를 하나의 노드에 저장하는 방식을 사용하였습니다.

<module name="Subject" version="1">
  <OnggiTableObj name="SubjectUser" g-type="SubjectBook" id-column="Subject/SubjectUser/name">
    <OnggiColumnProperty name="name" g-type="gchararray"/>
  </OnggiTableObj>
</module>

하지만 이러한 방식은 속성으로 기록할 수 있는 속성의 종류가 제한되어 있어서 객체 등을 속성 값으로 지정해야 할때, 이름을 지정해야 합니다. 하지만 이러한 방식은 상황에 따라서는 어색할 수 있어 아래와 같이 객체의 속성치를 하위 노드로 두는 방식입니다.

<module name="Subject">
  <version>1</version>

  <element type="OnggiTableObj" name="User">
    <g-type> SubjectBook </g-type>

    <id-column type="OnggiColumnProperty" name="name">
      <g-type> gchararray </g-type>
    </id-column>
  </element>
</module>

이러한 변경으로 인해, 하위 객체로 추가되는 노드와 속성으로 추가되는 노드를 구분하게 될 필요가 있었습니다. 따라서 노드의 종류가 추가 되었습니다. 그리고 속성으로 추가되는 노드의 경우, 속성의 이름을 구분할 필요가 있었습니다. 그래서 객체의 태그명이 추가 되었습니다.

또한 OnggiConstructionNode는 지나치게 긴 이름인 것 같아, OnggiCNode로 변경하였습니다.

GQuark onggi_cnode_get_kind (OnggiCNode *node);
const gchar *onggi_cnode_get_tag (OnggiCNode *node);

이러한 변경에 덧붙여서 GClosure를 기입하여, 다른 객체의 속성으로 사용하거나 시그널에 연결하는 등을 수행할 수 있는 등의 기능을 추가하였습니다.

이외에도 추가로 보완해야 할 점이 존재하고, 테스트가 되지 않은 기능들이 존재합니다. 따라서 큰 고개는 넘었고, 아직은 진행중이라고 보면 됩니다.


4. 이후?

 Vala로 건너갈려고 생각하고 있습니다. C가 객체지향 언어가 아니다보니, 클래스를 정의하기 위해선, 인스턴스 구조체와 클래스 구조체를 정의해 주고, 속성 등에 있어서도 불편함이 적지 않기 때문입니다. 이러한 불편함에 지쳐버린 나란 사람~!

Computing 2016년 12월 31일의 Onggi 2016/12/31 19:48 by WSID

어쩌다보니 어느새 2016년 마지막 날이 찾아오는군요..!

사실은 지지난주에 글을 올렸어야 했는데, 여러가지로 바빴고, 따라서 추가된 기능도 별로 없기에 이번에 글을 올려 봅니다.

일단 추가된 기능은 유감스럽게도 단 하나.. 이군요...


1. OnggiSaveUnit

객체에 담길 수 있는 데이터는 다양한 크기를 가집니다. 작게는 몇개의 정수부터, 크게는 MB 단위 크기의 사진 등과 같이 다양한 데이터가 저장됩니다. 객체는 자주 변경될 수 있습니다. 그러나 작은 부분은 자주 바뀐다 하더라도 큰 부분은 바뀌는 일이 드뭅니다. 따라서 객체가 바뀔 때마다 전체를 저장하는 것은 비효율성을 가져올 수도 있습니다.

따라서 객체를 여러 부분으로 나눌 수 있도록 OnggiSaveUnit을 추가하였습니다.

OnggiTableObj는 OnggiSaveUnit을 어려개 가집니다.

  onggi_table_obj_add_save_unit (table, save_unit);

OnggiSaveUnit은 OnggiColumn을 여러개 가지며, 각각의 이름을 가지고 있습니다. OnggiTableObj의 모든 컬럼은 적어도 한 OnggiSaveUint에 속하며, 어디에도 소속되지 않는 컬럼은 기본 save unit에 소속됩니다.

  onggi_save_unit_add_column (save_unit, a_column);

OnggiTableObj는 부모 타입의 객체를 저장하는 다른 OnggiTableObj의 OnggiSaveUnit에 "이름이 같은 자신의 OnggiSaveUnit"을 이을 수 있습니다. 다시 말해, 추가한 save unit의 이름이, 베이스가 되는 OnggiTableObj의 한 save unit과 이름이 같다면 하나인 것처럼 이어진다는 것입니다.

이렇게 구성한 것은 save unit을 의미에 따라 구성할 수 있게 하는 것과, save unit이 불필요하게 많아지는 것을 막기 이해서입니다.


애초에 OnggiSaveUnit을 구성한 것은 큰 데이터를 처리하기 위해 방법을 구상하다 나온 것 중에 하나인지라, 제가 쓸땐 아마 한개의 save unit을 굴리게 되지 않을까.. 합니다..

만들어 놓고 쓰질 않는다...





일단은 여기까지.. 이상입니다.

2016년 12월 5일의 Onggi 2016/12/05 02:49 by WSID

드디어 2주가 지나고 썰을 풀어봅니다. 그림을 그리다가 자꾸 다운되서 그림을 안 넣으려고 했습니다만, 살짝 낙서 느낌으로 그려서 올려봅니다.


그리다보니 의미를 모르게 된 그림...;;

1. 삭제 및 되돌리기 기능 구현

저번에는 새로운 객체를 저장하는 기능을 구현하였습니다. 이번에는 삭제와 되돌리기를 구현해 보았습니다.

객체의 변경이나 삭제를 표현하기 위해 Holder를 표시할 수 있도록 하였습니다. 새로운 객체를 추가할 때에도, Holder에는 "새 객체" 표시가 됩니다. 상태가 늘어나는 것을 막기 위해 변경과 삭제는 각각 따로 표기할 수 있도록 하였습니다.

    onggi_holder_group_include_instance (store, instance);
    onggi_holder_group_mark_removed_for (store, instance);
    onggi_holder_group_mark_modified_for (store, instance);
    ...

그리고 이러한 사항을 저장하거나 아니면 되돌릴 수 있도록 하였습니다.

    onggi_store_save (store, &error);
    onggi_store_revert (store, &error);


2. Store에 Holder와 객체를 얻어오는 함수 추가

OnggiHolderGroup을 통해 OnggiHolder나 객체를 얻을 수 있습니다. 그러나 OnggiHolderGroup을 얻는 것이 번거로울 수 있습니다. 편의를 위해 OnggiStore에서 Holder나 객체를 얻을 수 있도록 함수들을 추가하였습니다.

    onggi_store_get_holder (store, MY_TYPE_OBJECT, id, &error);
    onggi_store_get_instance (store, MY_TYPE_OBJECT, id, &error);

    onggi_store_get_holder_for (store, some_object);

또한 1.에 해당하는 함수들도 추가하였습니다. 객체에 대한 함수들은 따로 객체에서 타입을 얻을 수 있기 때문에 타입 매개변수를 따로 받지 않습니다.

    onggi_store_include_instance (store, some_object);



3. OnggiHolderDelayer

불러온 객체를 사용하고 나면, 필요 없을 때는 파기할 수 있습니다. 하지만 파기된 객체가 다시 필요할 땐, 다시 불러와야 합니다. 일반적으로 파기된 객체들은 한참동안 사용되지 않습니다. 불행하게도 파기된 객체를 다시 불러와야 하는 경우도 생깁니다. 

이러한 상황이 자주 발생한다면 객체의 불필요한 파기와 생성이 반복되어 성능상으로 안좋은 상황이 생깁니다. 이를 방지하기 위해 객체가 필요 없어져도, 금방 다시 사용해야 할 경우를 대비하여 유지하고자 합니다.

따라서 "객체를 유지할 표시"가 필요합니다. 이러한 표시로 사용하기 위해 OnggiHolderDelayer의 클래스를 구성하였습니다. 이 클래스의 hold 속성을 통해 객체를 유지할지, 객체를 유지하지 않을지 표시합니다.

    struct _OnggiHolderDelayerClass {
        GObjectClass _parent;
        void (*on_load) (OnggiHolderDelayer *delayer);
        void (*on_invalidate) (OnggiHolderDelayer *delayer);
        void (*on_get) (OnggiHolderDelayer *delayer);
        void (*on_peek) (OnggiHolderDelayer *delayer);
    };

    onggi_holder_delayer_set_hold (holder, hold);

    onggi_holder_add_delayer (holder, delayer);
    onggi_holder_remove_delayer (holder, delayer);


OnggiHolderDelayer는 추상 클래스입니다. 현재의 유일한 구현체는 OnggiHolderDelayerTimeout 밖에 없습니다. 이 구현체는 지정된 시간동안 hold 속성을 '참'으로 유지해 놓습니다.

    delayer = onggi_holder_delayer_timeout_new (60000); // 1분 동안 객체를 유지합니다.



4. 객체를 강제로 무효화 하기

OnggiHolder에서 객체를 강제로 무효화 하는 함수도 추가하였습니다. 아직은 쓸모를 찾지 못했습니다. 하지만 언젠가 쓸모가 있으리라 생각됩니다.

    onggi_holder_invalidate_instance (holder);



추후 계획

1. 내부 정리

일단 기능 추가는 이정도 해두고 내부 정리도 조금 할 겸, 테스트 케이스도 추가 해야 할 것 같습니다.
그리고 객체 저장이나 불러오기 등의 동작들도 취소 가능한 동작으로 구성해야 할 것 같습니다.


2. OnggiConstruction에 기능 추가

객체의 신호를 연결하는 기능을 추가하고자 합니다. GObject는 다른 함수들이 연결될 수 있는 '신호' 기능을 제공하며, 객체가 신호를 방출하면, 연결된 함수들이 호출됩니다.

    // object의 some-signal에 함수 my_some_signal_handler을 연결
    g_object_connect (object, "some-signal", (GCallback *) my_some_signal_handler, NULL);

    // 객체의 신호를 방출 - 이 신호에 연결된 함수들도 같이 호출된다!
    g_signal_emit (self, SIG_SOME_SIGNAL, 0, arg_0, arg_1);

이러한 기능은 다양한 상황에서 쓰이곤 합니다. 예를 들면, 버튼 등과 같은 GUI 컨트롤에서 이벤트 관련 기능을 제공하기 위해서도 쓰이곤 하지만, 함수 내부에서 신호를 발생시켜, 함수의 행동을 변경하거나 추가할 여지를 주기도 합니다.

OnggiConstruction에서 신호에 연결할 수 있다면, 기능의 추가에 대한 제약 사항이 줄어들 것 같습니다.

이상입니다. 'u'

Computing 2016년 11월 21일 혼자 조용히 Onggi를 작성하던 썰... 2016/11/22 19:39 by WSID


서론

혼자 조용히 주섬 주섬 만들고 있던 라이브러리에 대한 썰이긴 합니다만, 뭔가 만드는 것에 대해 썰을 풀고자 하는 것은 주변의 여기 저기 등에서 "개발자의 업데이트 뉴스"라던가 "이번주의 업뎃 사항" 등으로 주기적으로 올려 놓는 것을 보고 저도 이런 것을 만드는 게 좋지 않을까 하는 생각이 들었습니다. 그래서 저도 "Onggi의 진행 사항을 주기적으로 올려보자"고 마음 먹었습니다만, 체력의 문제라던가 피로가 쌓였다던가 하는 이유로 올리진 못했습니다... (....)

원래를 2주마다 올리는 것을 목표로 했지만, 너무 많은 시간이 지났고, 시간 순서대로 글을 쓰자니 다소 햇갈리는 부분이 있고, 심지어 까먹기도 해서, 글이 정리가 안되었습니다. 그래서 일단 전체 구성을 니열한 다음에, 각각의 개별 구성에 대해 글을 써보도록 하겠습니다.

그리고 불필요하게 복잡하다던가 하는 부분은, 제가 센스가 부족하기 때문이므로, 양해 부탁드립니다. (.....)

이어지는 내용

새로 산 가방을 자랑해봅니다. [Aizim 305I] 2016/11/10 14:55 by WSID

안녕하십니까~! 이틀 전 글에서 쓴 바와 같이, 가방을 새로 샀습니다.

글을 따로 쓰게 된 건, 조금 분량의 글이지만, 가방에 대한 내용을 다 쓴다면 어느정도의 분량이 되기 때문입니다. 따라서 이렇게 새로 글을 쓰게 되었습니다.

전반적으로는 크고 튼튼한 사각형 모양을 하고 있습니다.

이어지는 자세한 사항

1 2 3 4 5 6 7 8 9 10 다음