본문 바로가기

언어/Lazarus

SQLite3을 설치하는 방법

출처: https://www.tweaking4all.com/software-development/lazarus-development/lazarus-pascal-getting-started-with-sqlite/#GettingstartedwithSQLiteunderLinuxUbuntuRaspbian


Getting started with SQLite under Linux (Ubuntu/Raspbian)

I have Ubuntu (v12 at the moment) available on a virtual machine and found that the easiest way to follow the following steps. These steps work for Lazarus on Raspberry Pi 2 Model B as well.

On your developer machine (assuming you have Lazarus 1.0.x or newer installed), first install SQLite3 with apt-get.

sudo apt-get install sqlite3 libsqlite3-dev

You’ll now find the SQLite library in the following location: /usr/lib/i386-linux-gnu/libsqlite3.so.0 (Note: for Raspberry Pi 2 model B /usr/lib/arm-linux-gnueabihf/libsqlite3.so.0):
Tip : If you could not find the file there, use the “locate” statement to determine the location of “libsqlite3.so.0”.

The next step, and I’m sure there might be better ways to do this, is to copy the library in your project folder which I always like to do, just to make sure I’m testing with the right library file, and to help me make a distribution zip file later on.

In the example below we have our project files saved in ~/Desktop/MyProject and in this step we will also rename the file to libsqlite3.so .

Finally, we’d like Lazarus to find the library during design time and for that we make a soft link in the /usr/lib/ directory which we will call ‘libsqlite3.so’ as well (it’s what Lazarus will be looking for).

Note : I noticed that in some forums that people mention ‘/usr/lib64’ for 64-bit systems, but I cannot confirm this to be true or not.

Note : libsqlite3.so.0 is actually just a symbolic link to a particular library version, for example libsqlite3.so.0.8.6. Copying it will copy the actual binary, not the link. Also note that the path under Raspbian is different.

1
2
3
4
cd ~/Desktop/MyProject
cp /usr/lib/i386-linux-gnu/libsqlite3.so.0 ./libsqlite3.so

sudo ln -s /usr/lib/i386-linux-gnu/libsqlite3.so.0 /usr/lib/libsqlite3.so

Next drop the TSQLite3Connection component from the SQLdb tab on your main form.

Lazarus Linux (Ubuntu) - Add the TSQLite3Connection to your From

Lazarus Linux (Ubuntu) – Add the TSQLite3Connection to your From

Now to make sure that our new application will use the library in our project folder, we will need to tell our application in the onCreate event of the mainform, where to find the library:

1
2
3
4
procedure TForm1.FormCreate(Sender: TObject);
begin
  SQLiteLibraryName:='./libsqlite3.so.0';
end;

Getting started with SQLite under Windows

Using SQLite3 under Windows is a matter of copying the DLL into your project folder.

You can download the DLL from the SQLite Download Page under Precompiled Binaries for Windows (at the time of writing this article, it’s the second file that starts with ‘sqlite-dll’).

After downloading, unzip the file and copy the sqlite3.dll  into your project directory.

For Lazarus to find the DLL at design time, you will need to copy the sqlite3.dll to c:\windows\system  as well.

Next drop the TSQLite3Connection component from the SQLdb tab on your main form.

Lazarus Windows - Add the TSQLite3Connection to your From

Lazarus Windows – Add the TSQLite3Connection to your From

Now to make sure that our new application will use the library in our project folder, we will need to tell our application in the onCreate event of the mainform, where to find the library:

1
2
3
4
procedure TForm1.FormCreate(Sender: TObject);
begin
  SQLiteLibraryName:='sqlite3.dll';
end;

Your Database file …

As mentioned before: SQLite uses a single file for an entire database. When you start your project however, you will most likely not have that file yet …

The cool part of using SQLite with the TSQLite3Connection is that when you connect to a database file, and the file doesn’t exist, then SQLite will create one for you. It’s an empty database of course, but it’s there.

There are several ways and tools to get your database populated with tables and such. An overview of available tools can be found on the SQLite Management Tools Page. Quite a few of these tools are commercial or only useful under Windows, but some offer a trial or freeware version.

Valentina Studio – Cross platform and free

Valentina Studio is a pretty darn good editor for SQLite (and others) and is available for MacOS X, Linux and Windows in either a freeware version or a commercial version. If I could find a downside then it would be that the SQL generated in the visual designer cannot be copied with the current freeware version.

You can download it from the Valentina Studio Homepage or additionally for Mac users in the Mac App Store.

Once installed, Valentina will offer a free serial number after registration (also free).

Getting started

My preferred process might not be your preferred process … to each it’s own. My process usually involves the following steps:

  1. Determine data needs and table design.
  2. Create a SQLite database using Valentina.
  3. Create tables (based on step 1, in the database of step 2).
  4. Develop Lazarus application – possibly modify your database if needed.
  5. Dump SQL statements to create tables.
  6. Add the table creation statements to my application so it can create tables if the database file is missing.

Step 1 – Determine Data need

This step should be pretty obvious: designing tables based on the expected data need of your to build application.

My first design will typically be a rough one, which I fine tune as development of an application moves forward.

Step 2  – Create Database and Tables.

I usually do in Valentina Studio.

After downloading, installing and registrating of Valentina Studio, click in the menu “File”  New Database” and choose “SQLite files” from the popup window and click “OK“. A new window will open allowing you to enter the desired filename and file location.

All pretty obvious steps, but it can happen that Valentina complains that you’re trying to create a database file in a not legit location. Valentina limits where you can store your database file, but when you click “Edit Preferences” you can simply add your project folder as a “legit” location.

Once you have you database created, you can start creating tables.

Step 3 – Development of your application

The development of your application, will require that you close Valentina – after all, SQLite is a single user database engine and therefor we cannot have your application and Valentina connected to the database at the same time.

This will also be the case when you have your connection active in your form during design time.
Before running your new application make sure to set the “Connected” property of the TSQLite3Connection to “FALSE“.

This also means that your application will have to re-enable the connection when it starts, which can be done for example in the onCreate event of your mainform. See previous informtion when it comes to setting the SQLiteLibraryName – which is needed under Linux and Windows, but can be omitted under MacOS X.

1
2
3
4
5
procedure TForm1.FormCreate(Sender: TObject);
begin
  SQLiteLibraryName:='sqlite3.dll';
  SQLite3Connection1.Open;
end;

Now that we have our connection ready we need to add a TSQLTransaction component to our form as well (also found onder the SQLdb component tab) and connect it to the TSQLite3Connection component by setting it’s “Database” property to the TSQLite3Connection we added earlier.

Now we can do the usual adding of the usual Queries and Tables (all use the TSQLQuery component) – you will, even for tables, have to enter the proper query to retrieve data in the “SQL” property of the TSQLQuery component. For a simple table for example:

SELECT * FROM movies ORDER BY filename;

Don’t forget that for data-aware components you’ll also need to add TDataSource for each query that will be accessed through these data-aware components. TDataSource can be found under the “Data Access” component tab.

Step 4 – Dump SQL for database

In this step your application should already be good to go.

I always like to have the application create it’s database when it’s missing and for this I need all SQL statements to create tables etc. Valentina is very helpful here: Right click the database in Valentina and choose “Create Dump” from the popup menu.

In the upcoming window select “SQL” as the “Dump kind“, and click “Next“.
In the next window select “Structure only“, or “Structure and Records” if you need the data as well, and click “Next“.
In the following window I usually make sure that NOTHING is selected and click “Next“.
Finally we get a window where we can enter filename and destination of the SQL dump.

The resulting SQL code can now be opened with a simple text editor so you can copy it and paste it into your Lazarus Pascal code.

Step 5 – Code to create missing databases

Again, I’m not worlds best developer, but this is what I usually do.

First I create a procedure that will handle all this. Let’s call it “StartDatabase“.

In this procedure we will first set the SQLite library (if needed).

After that we will determine if the database file already exists and store our findings in a boolean (createTables in our example).

If the folder for the database file does not exist, then we will create it now.

Next we will open the database connection, well knowing that the database will be totally empty if the file didn’t exist before.

Once we opened the database connection, and the file didn’t exist before, tables etc. must be created before our TSQLQuery components (for example) access the tables. For the execution of these SQL statements we use the TSQLite3Connection.ExecuteDirect() function so we do not need additional components to run the queries.

Database Location 

You’re free to determine where the database file of your application should be. However, keeping cross platform development in mind, you should be aware of some limitations.

MacOS X for example will typically not allow you to store your data in the same directory where the application is installed – which has to do with access rights and security.

Locations, like where temporary files are stored, are not consistent either even on the same platform (Windows likes temp locations all over the place, depending on your Windows version).

Lazarus offers a cross platform “AppConfigDir” – this is also the location where for example INI files and registry data are stored.
Personally I think this is not a bad location for your database and the function GetAppConfigDir() helps you do that cross platform.

Find below example code how this can be done. I’m using a simple table for managing movies as an illustration.

The procedure “StartDatabase” is the first thing I’d call from the form’s onCreate event. After this procedure has been completed, I open the TQSLQuery component(s) and other database related components if needed.

The database file in this example is located in the application configuration folder by using GetAppConfiDir() – the parameter “false” indicates that it’s not a global config directory but only for this application. Of course the file needs a name, ‘mydatabase.db’ in this case.

Under MacOS X this folder can be found in your home directory, for example: ~/.config/MyProject/mydatabase.db

Under Windows XP this would be: C:\Documents and Settings\<username>\Local Settings\Application Data\MyProject\mydatabase.db

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
procedure TForm1.StartDatabase;
var createTables:boolean;
begin
  {$IFDEF UNIX}  // Linux
    {$IFNDEF DARWIN}
      SQLiteLibraryName := './libsqlite3.so';
    {$ENDIF}
  {$ENDIF}

  {$IFDEF WINDOWS} // Windows
  SQLiteLibraryName := 'sqlite3.dll';
  {$ENDIF}

  SQLite3Connection.DatabaseName:=GetAppConfigDir(false) + 'mydatabase.db';

  if not DirectoryExists(GetAppConfigDir(false)) then  // Check if config directory exists
    MkDir(GetAppConfigDir(false));                // if not: create it

  createTables := not FileExists(SQLite3Connection.DatabaseName); // no file = create new tables

  SQLite3Connection.Open;
  SQLTransaction1.Active:=true;

  if createTables then
    begin
      SQLite3Connection.ExecuteDirect('CREATE TABLE "movies"('+
                    ' "bitrate" Numeric,'+
                    ' "duration" DateTime,'+
                    ' "fileextension" Text,'+
                    ' "filename" Text NOT NULL,'+
                    ' "filesize" Numeric,'+
                    ' "filesizetext" Text,'+
                    ' "format_long" Text,'+
                    ' "id" Integer NOT NULL PRIMARY KEY AUTOINCREMENT,'+
                    ' "path" Text);');

      SQLite3Connection.ExecuteDirect('CREATE INDEX "movies_filename_idx" ON "movies"( "filename" );');
      SQLite3Connection.ExecuteDirect('CREATE UNIQUE INDEX "movies_id_idx" ON "movies"( "id" );');

      SQLTransaction1.Commit;
    end;
end;

As you can see: once you know how it’s done, using SQLite isn’t all that hard – even cross platform.

Tips and Tricks

As I have worked more with SQLite under Lazarus, I have tips and tricks, of issues that seem impossible to fix, which I’d like to share here.

A TEXT field shows a (memo) in a DBGrid

Sometimes, a text field of a database table or query will be interpreted as a ftMemo blob, and the grid will show “(memo)” instead of the actual text. Quite annoying at times and I’m still surprised that this happens to remain unaddressed in both Lazarus and Delphi … Anyhoo .. how do we fix this?

Option 1 (best) – Modify your SQL Query

Now this option has the intend to make the “Memo Blob” look like a regular string. We can do this with a simply type cast.
Note : this might be slightly different, depending on your SQL Database. I have used this with SQLite, and MySQL, and heard it works in PostgreSQL as well.
Say your query is something like this:

1
2
3
4
5
SELECT
  "Filename", 
  "Date"
FROM
  "mytable";

And let’s assume “Filename” is the offending field.
Now (make sure to remove the fields from the TQuery component!) change your query by casting the TEXT as a VARCHAR like so:

1
2
3
4
5
SELECT
  CAST( "Filename" AS VARCHAR) AS "Filename", 
  "Date"
FROM
  "mytable";

You will now see that the actual text is being displayed and not the “(memo)” text.

Option 2 (when option 1 fails) – OnGetText Event

This works only at Runtime, and takes a little bit more work.

First we need to add fields to our TQuery.
Right click the TQuery and select “Edit Fields”.
In the upcoming window click the “+” button to at least add the field that shows as “(memo)”.

Now click the newly added field. You’ll see that a TMemoField has been added in the object inspector.
Click the “Events” tab in the object inspector and double click the “OnGetText” event.

Now add this code to the event handler (assuming: TQuery = qrySomeQuery, fieldname = “SomeField”, which creates the TMemoField called “qrySomeQuerySomeField”):

1
2
aText := Sender.AsString;
DisplayText:=true;

So we get something like this, which now makes (at runtime) show the actual text instead if (memo):

1
2
3
4
5
procedure TForm1.qrySomeQuerySomeFieldGetText(Sender: TField; var aText: string; DisplayText: Boolean);
begin
  aText := Sender.AsString;
  DisplayText:=true;
end;

Resetting Auto Increment Fields

When flushing tables in SQLite, or removing a lot of records, you might want to reset the auto increment fields counter (1 or the next available unused number).

The following SQL statement does this for ALL tables (yes: it’s safe to do this, records of your tables will not be deleted or modified!):

1
DELETE FROM sqlite_sequence;

Or like so for a specific table:

1
DELETE FROM sqlite_sequence WHERE name='your_table';

Compact (Vacuum) your Database file

This one proved pretty tricky – cleaning up and compacting your database at runtime, but a just slightly modified trick that I found in the Lazarus Forum makes it possible.
Normally you’d see an error message (Cannot vacuum from within a transaction) when trying to execute the “VACUUM” statement through a TSQLQuery component.

First add the unit “sqlite3ds” to your “Uses” clause.

Next add and call this procedure in your code.
It will take the name of your existing TSQLite3Connection (assuming you use only one – which is pretty common with SQLite), close the connection, vacuum (compact) your database, and restore the TSQLite3Connection if it was open when you called this function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure TForm1.SQLiteVacuum(db:TSQLite3Connection);
var tmpDataset   : TSqlite3Dataset;
    wasConnected : boolean;
begin
  wasConnected := db.Connected;

  db.Close;
  repeat
  until not db.Connected;

  tmpDataset := TSqlite3Dataset.Create(nil);
  tmpDataset.FileName:=SQLConnection.DatabaseName;
  tmpDataset.ExecSQL('VACUUM;');
  tmpDataset.Free;

  db.Connected:=wasConnected;
end;

Order Text as Numbers

When trying to sort text as number in SQLite, you’ll run into some issues where it does not sort numerical.
With a little trick we can order text numerically, for fields with numbers in it.
In my example, I had a field “video_mode” with values like “480p”, “720p”, “1080p” and “2160p”.
The normal sorting by using “ORDER BY video_mode” will fail and result in:

1080p
2160p
480p
720p

Not exactly numerical (a.k.a. “natural”), or at least not the way we expected it ….

If we add a CAST to INTEGER (in the ORDER BY) however, we DO get numerical sorting, even if there is text in the field:

ORDER BY CAST(video_mode AS INTEGER)
or
ORDER BY CAST(video_mode AS DECIMAL)

The result is the desired order:

480p
720p
1080p
2160p

Sort Text, Case Insensitive

When you do a ORDER BY on a field, say “title”, which has for example the following values,

title
-----
 c
 a
 D
 Z
 B
 X

then with:

SELECT … ORDER BY title ASC;

You’ll get:

 B
 D
 X
 Z
 a
 c

To sort this case insensitive use:

SELECT … ORDER BY title COLLATE NOCASE ASC;

and you’ll get the right order:

 a
 B
 c
 D
 X
 Z

Additional Resources

Some additional resources that might prove useful if you’re starting to dig into Lazarus and SQLite:

  64





리눅스에서 SQLite 시작하기 (Ubuntu / Raspbian)

가상 머신에서 사용할 수있는 우분투 (v12)가 있으며 다음 단계를 따르는 것이 가장 쉬운 방법이라는 것을 알았습니다. 이 단계 는 Raspberry Pi 2 Model B의 나사로에서도 작동 합니다.

개발자 머신에서 (Lazarus 1.0.x 이상이 설치되었다고 가정), 먼저 apt-get로 SQLite3를 설치하십시오.

sudo apt-get install sqlite3 libsqlite3-dev

이제 다음 위치에서 SQLite 라이브러리를 찾을 수 있습니다.  (참고 : Raspberry Pi 2 모델 B의 경우 ) :   : 파일을 찾을 수 없으면 "locate"문을 사용하여 "libsqlite3.so .0 "./usr/lib/i386-linux-gnu/libsqlite3.so.0/usr/lib/arm-linux-gnueabihf/libsqlite3.so.0

다음 단계는이 작업을 수행하는 더 좋은 방법이 될 수 있다고 확신합니다. 항상 프로젝트 라이브러리에 라이브러리를 복사하고, 내가 올바른 라이브러리 파일로 테스트하고 있는지, 나중에 배포 zip 파일을 만들 수 있도록 도와주세요.

아래 예제에서는 프로젝트 파일을 저장  하고이 단계에서 파일의 이름을 바꿀 것  입니다.~/Desktop/MyProjectlibsqlite3.so

마지막으로 우리는 Lazarus가 디자인 타임에 라이브러리를 찾을 수 있도록하고,  디렉토리 에서 libazqlite3.so라고 하는 소프트 링크를 만든다. (나사로가 찾고있는 것이다.)/usr/lib/

참고 : 일부 포럼에서는 사람들이 64 비트 시스템의 경우 '/ usr / lib64'를 언급하지만 이것이 사실인지 아닌지를 확인할 수없는 것으로 나타났습니다.

참고 : libsqlite3.so.0은 실제로 특정 라이브러리 버전에 대한 심볼 링크입니다 (예 : libsqlite3.so.0.8.6). 복사하는 것은 링크가 아닌 실제 바이너리를 복사합니다. 또한 Raspbian 아래의 경로가 다릅니다.




4
cd ~ / Desktop / MyProject 
cp / usr / lib / i386-linux-gnu / libsqlite3.so.0. / libsqlite3.so 

sudo ln -s / usr / lib / i386-linux-gnu / libsqlite3.so.0 / usr / lib / libsqlite3.so

그런 다음 기본 폼 의 SQLdb 탭 에서 TSQLite3Connection 구성 요소를 삭제합니다  .

Lazarus Linux (Ubuntu) - 당신의 TSQLite3Connection 추가

Lazarus Linux (Ubuntu) - 당신의 TSQLite3Connection 추가

이제 우리의 새로운 응용 프로그램이 프로젝트 폴더에서 라이브러리를 사용할 수 있도록하기 위해 mainform 의 onCreate 이벤트 에서 응용 프로그램에 라이브러리를 찾을 위치를 알려줘야 합니다.



4
procedure TForm1.FormCreate(Sender: TObject);
begin
  SQLiteLibraryName:='./libsqlite3.so.0';
end;

Windows에서 SQLite 시작하기

Windows에서 SQLite3을 사용하는 것은 프로젝트 폴더에 DLL을 복사하는 것입니다.

당신은에서 DLL 다운로드 할 수 있습니다 SQLite는 다운로드 페이지 에서  Windows 용 미리 컴파일 된 바이너리를 (이 문서를 작성하는 시점에, 그것은 'sqlite가-DLL'로 시작하는 두 번째 파일입니다).

다운로드가 완료되면 파일의 압축을 풀고 sqlite3.dll  프로젝트 디렉토리로 복사하십시오 .

Lazarus가 디자인 타임에 DLL을 찾으려면 sqlite3.dll도 복사해야합니다 c:\windows\system  .

그런 다음  기본 폼  의 SQLdb 탭 에서 TSQLite3Connection 구성 요소를  삭제합니다  .

Lazarus Windows - 당신의 TSQLite3Connection 추가

Lazarus Windows - 당신의 TSQLite3Connection 추가

이제 우리의 새로운 응용 프로그램이 프로젝트 폴더에서 라이브러리를 사용할 수 있도록하기 위해  mainform 의 onCreate 이벤트 에서 응용 프로그램에 라이브러리를 찾을 위치를 알려줘야  합니다.


1
2
3
4
procedure TForm1.FormCreate(Sender: TObject);
begin
  SQLiteLibraryName:='sqlite3.dll';
end;

데이터베이스 파일 ...

앞에서 언급했듯이 : SQLite는 전체 데이터베이스에 단일 파일을 사용합니다. 그러나 프로젝트를 시작하면 아직 그 파일이 없을 것입니다 ...

TSQLite3Connection과 함께 SQLite를 사용하는 멋진 부분은 데이터베이스 파일에 연결할 때 파일이 존재하지 않는다면 SQLite가이를 생성한다는 것입니다. 물론 비어있는 데이터베이스이지만 거기에 있습니다.

데이터베이스를 테이블 등으로 채우는 데는 여러 가지 방법과 도구가 있습니다. 사용 가능한 도구에 대한 개요는 SQLite 관리 도구 페이지 에서 찾을 수 있습니다 이 툴 중 상당수는 상업용이거나 Windows에서만 유용하지만 일부는 시험 버전이나 프리웨어 버전을 제공합니다.

발렌티나 스튜디오 - 크로스 플랫폼 및 무료

Valentina Studio는 SQLite (및 기타)에 대한 훌륭한 편집기이며 MacOS X, Linux 및 Windows에서 프리웨어 버전 또는 상용 버전으로 사용할 수 있습니다. 아래쪽을 발견 할 수 있다면 비주얼 디자이너에서 생성 된 SQL을 현재 프리웨어 버전으로 복사 할 수 없다는 것입니다.

Valentina Studio Homepage 에서 다운로드  하거나 Mac App Store 에서 Mac 사용자를 위해 추가로 다운로드 할 수 있습니다 .

Valentina가 설치되면 등록 후 무료 일련 번호를 제공합니다 (무료).

시작하기

내 선호하는 프로세스가 자신이 선호하는 프로세스가 아닐 수도 있습니다. 내 과정에는 일반적으로 다음 단계가 포함됩니다.

  1. 데이터 요구 사항 및 테이블 디자인을 결정합니다.
  2. Valentina를 사용하여 SQLite 데이터베이스를 생성하십시오 .
  3. 테이블을 만듭니다 (1 단계에서 2 단계의 데이터베이스에 기반).
  4. Lazarus 응용 프로그램을 개발하십시오 - 필요할 경우 데이터베이스를 수정하십시오.
  5. SQL 문을 덤프하여 테이블을 작성하십시오.
  6. 테이블 작성 명령.을 응용 프로그램에 추가하여 데이터베이스 파일이 누락 된 경우 테이블을 작성할 수 있습니다.

1 단계 - 데이터 요구 결정

이 단계는 매우 분명해야합니다 : 응용 프로그램을 빌드하는 데 필요한 예상 데이터를 기반으로 테이블을 디자인하십시오.

첫 번째 디자인은 대개 거친 모양 일 것이므로 애플리케이션 개발이 진행됨에 따라 미세 조정됩니다.

2 단계 - 데이터베이스 및 테이블 생성.

나는 Valentina Studio에서 보통한다.

Valentina Studio를 다운로드, 설치 및 등록한 후 " 파일 "  새 데이터베이스 " 메뉴를 클릭 하고 팝업 창에서 SQLite 파일 "을 선택 하고 " 확인 "을 클릭하십시오 원하는 파일 이름 과 파일 위치 를 입력 할 수있는 새 창이 열립니다 .

꽤 명백한 모든 단계가 있지만, Valentina가 합법적이지 않은 위치에 데이터베이스 파일을 만들려고한다고 불평하는 경우가 발생할 수 있습니다. Valentina는 데이터베이스 파일을 저장할 수있는 위치를 제한하지만 " 편집 기본 설정 "을 클릭 하면 프로젝트 폴더를 "합법적 인"위치로 간단히 추가 할 수 있습니다.

일단 데이터베이스를 만들면 테이블을 만들 수 있습니다.

3 단계 - 신청서 개발

응용 프로그램을 개발하려면 Valentina 를 닫아야합니다. 결국 SQLite는 단일 사용자 데이터베이스 엔진이므로 응용 프로그램과 Valentina를 동시에 데이터베이스에 연결할 수 없습니다.

디자인 타임에 양식에서 연결을 활성화 한 경우에도 마찬가지입니다. 
새 응용 프로그램 을 실행하기 전에 TSQLite3Connection 의 " Connected "속성을 " FALSE "로 설정하십시오.

이것은 또한 응용 프로그램이 시작할 때 연결을 다시 활성화해야 함을 의미합니다. 예를 들어 메인 폼의 onCreate 이벤트에서이를 수행 할 수 있습니다. Linux 및 Windows에서 필요하지만 SQLiteLibraryName을 설정할 때 이전 정보를 참조하십시오. MacOS X에서는 생략 할 수 있습니다.





5
TForm1 프로 시저 FormCreate ( 보낸 사람 : TObject   SQLiteLibraryName 
시작 'sqlite3.dll'   SQLite3Connection1 열기 끝 ;


이제 연결 준비가 완료 되었으므로 우리 양식에 TSQLTransaction 구성 요소 를 추가하고 ( SQLdb 구성 요소 탭에서도 찾을 수 있음) 이전에 추가 한 TSQLite3Connection에 Database "속성을 설정하여 TSQLite3Connection 구성 요소에 연결해야합니다 .

이제는 일반적인 쿼리와 테이블을 추가 할 수 있습니다. 모두 TSQLQuery 구성 요소를 사용합니다. 테이블의 경우에도 TSQLQuery 구성 요소의 "SQL"속성에서 데이터를 검색하기위한 적절한 쿼리를 입력해야합니다. 예를 들어 간단한 테이블의 경우 :

SELECT FROM 영화 ORDER BY 파일 이름;

데이터 인식 구성 요소의 경우 이러한 데이터 인식 구성 요소를 통해 액세스 할 각 쿼리에 TDataSource를 추가해야 함을 잊지 마십시오. TDataSource 는 " 데이터 액세스 "구성 요소 탭 아래에 있습니다.

4 단계 - 데이터베이스 SQL 덤프

이 단계에서 응용 프로그램은 이미 잘해야합니다.

나는 항상 응용 프로그램이 데이터베이스를 만들 때 누락 된 데이터베이스를 만들고 싶습니다.이 때문에 모든 SQL 문이 필요합니다. Valentina는 매우 유용합니다 : Valentina의 데이터베이스를 마우스 오른쪽 단추로 클릭 하고 팝업 메뉴에서 Create Dump "를 선택 하십시오 .

다가오는 창에서 " SQL "을 " 덤프 종류 "로 선택하고 " 다음 "을 클릭하십시오 
다음 창에서 데이터 만 필요하면 구조 만 "또는 "구조 및 레코드"를 선택하고 " 다음 "을 클릭하십시오 
다음 창에서는 보통 아무 것도 선택 하지 않았 는지 확인하고 다음 "을 클릭하십시오 
마지막으로 SQL 덤프의 파일 이름과 대상을 입력 할 수있는 창이 나타납니다.

생성 된 SQL 코드는 이제 간단한 텍스트 편집기로 열 수 있으므로 복사하여 Lazarus Pascal 코드에 붙여 넣을 수 있습니다.

5 단계 - 누락 된 데이터베이스를 만드는 코드

다시 말하지만, 나는 세계 최고의 개발자는 아니지만, 이것이 내가 일반적으로하는 일이다.

먼저 모든 것을 처리 할 프로 시저를 만듭니다. StartDatabase " 라고 부르 자 .

이 절차에서는 먼저 SQLite 라이브러리를 설정합니다 (필요한 경우).

그 후에 우리는 데이터베이스 파일이 이미 존재하는지 확인하고 결과를 부울 (이 예에서는 createTables )에 저장합니다.

데이터베이스 파일의 폴더가 존재하지 않으면 지금 생성 할 것입니다.

다음으로 우리는 데이터베이스 연결을 열 것입니다. 파일이 존재하지 않으면 데이터베이스가 완전히 비어 있음을 잘 알고 있습니다.

일단 데이터베이스 연결을 열고 파일이 존재하지 않으면 예를 들어 TSQLQuery 구성 요소가 테이블에 액세스하기 전에 테이블 등을 만들어야합니다. 이러한 SQL 문을 실행하기 위해 TSQLite3Connection.ExecuteDirect () 함수를 사용하므로 쿼리를 실행하는 데 추가 구성 요소가 필요하지 않습니다.

데이터베이스 위치 

애플리케이션 데이터베이스 파일의 위치를 ​​자유롭게 결정할 수 있습니다. 그러나 크로스 플랫폼 개발을 염두에두면 몇 가지 한계를 알고 있어야합니다.

예를 들어, MacOS X는 일반적으로 응용 프로그램이 설치된 동일한 디렉토리에 데이터를 저장하는 것을 허용하지 않습니다.이 권한은 액세스 권한 및 보안과 관련이 있습니다.

임시 파일이 저장된 위치와 같은 위치는 동일한 플랫폼에서도 일치하지 않습니다 (Windows는 Windows 버전에 따라 장소의 임시 위치를 좋아합니다).

Lazarus는 크로스 플랫폼 "AppConfigDir"을 제공합니다 - 이것은 또한 INI 파일과 레지스트리 데이터가 저장되는 위치입니다. 
개인적으로 나는 이것이 데이터베이스에 나쁜 위치가 아니며 GetAppConfigDir () 함수를 사용하여 크로스 플랫폼을 수행하는 데 도움이된다고 생각합니다.

이것이 어떻게 행해질 수 있는지 아래의 예제 코드를 찾으십시오. 나는 그림으로 영화를 관리하기위한 간단한 테이블을 사용하고있다.

"StartDatabase"프로시 저는 폼의 onCreate 이벤트에서 제일 먼저 호출 할 것입니다. 이 절차가 끝나면 필요한 경우 TQSLQuery 구성 요소 및 기타 데이터베이스 관련 구성 요소를 엽니 다.

이 예제의 데이터베이스 파일은 GetAppConfiDir ()을 사용하여 응용 프로그램 구성 폴더에 있습니다. "false"매개 변수는 전역 구성 디렉토리가 아니라이 응용 프로그램에만 해당된다는 것을 나타냅니다. 물론이 파일에는 'mydatabase.db'라는 이름이 필요합니다.

MacOS X에서이 폴더는 홈 디렉토리에서 찾을 수 있습니다. 예를 들면 다음과 같습니다. ~/.config/MyProject/mydatabase.db

Windows XP에서는 다음과 같습니다. C:\Documents and Settings\<username>\Local Settings\Application Data\MyProject\mydatabase.db


procedure TForm1.StartDatabase;
var createTables:boolean;
begin
  {$IFDEF UNIX}  // Linux
    {$IFNDEF DARWIN}
      SQLiteLibraryName := './libsqlite3.so';
    {$ENDIF}
  {$ENDIF}

  {$IFDEF WINDOWS} // Windows
  SQLiteLibraryName := 'sqlite3.dll';
  {$ENDIF}

  SQLite3Connection.DatabaseName:=GetAppConfigDir(false) + 'mydatabase.db';

  if not DirectoryExists(GetAppConfigDir(false)) then  // Check if config directory exists
    MkDir(GetAppConfigDir(false));                // if not: create it

  createTables := not FileExists(SQLite3Connection.DatabaseName); // no file = create new tables

  SQLite3Connection.Open;
  SQLTransaction1.Active:=true;

  if createTables then
    begin
      SQLite3Connection.ExecuteDirect('CREATE TABLE "movies"('+
                    ' "bitrate" Numeric,'+
                    ' "duration" DateTime,'+
                    ' "fileextension" Text,'+
                    ' "filename" Text NOT NULL,'+
                    ' "filesize" Numeric,'+
                    ' "filesizetext" Text,'+
                    ' "format_long" Text,'+
                    ' "id" Integer NOT NULL PRIMARY KEY AUTOINCREMENT,'+
                    ' "path" Text);');

      SQLite3Connection.ExecuteDirect('CREATE INDEX "movies_filename_idx" ON "movies"( "filename" );');
      SQLite3Connection.ExecuteDirect('CREATE UNIQUE INDEX "movies_id_idx" ON "movies"( "id" );');

      SQLTransaction1.Commit;
    end;
end;


보시다시피, 어떻게 완료되었는지 알게되면 SQLite를 사용하는 것이 모든 플랫폼에서 어렵지는 않습니다.

팁과 트릭

라자루스에서 SQLite로 더 많은 작업을 해왔으므로 수정이 불가능한 문제에 대한 팁과 트릭이 있습니다. 여기에서 공유하고 싶습니다.

TEXT 필드는 DBGrid의 (메모)를 보여줍니다.

경우에 따라 데이터베이스 테이블이나 쿼리의 텍스트 필드가 ftMemo BLOB로 해석되고 그리드는 실제 텍스트 대신 "(메모)"로 표시됩니다. 때때로 성가시다. 그리고 나는 이것이 나사로와 델파이 모두에서 다루어지지 않고 남아있게되는 것에 아직도 놀란다. .. Anyhoo.. 우리는 이것을 어떻게 고쳐 주느냐?

옵션 1 (최고) - SQL 쿼리 수정

이제이 옵션은 "Memo Blob"을 일반 문자열처럼 보이게 만들려고합니다. 우리는 단순히 타입 캐스트로 이것을 할 수 있습니다. 
참고 : 이것은 SQL 데이터베이스에 따라 약간 다를 수 있습니다. 나는 이것을 SQLite와 MySQL에서 사용했으며 PostgreSQL에서도 잘 작동한다고 들었다. 
쿼리가 다음과 같은 경우





5
SELECT 
  "Filename" 
  "Date" 
FROM 
  "mytable" ;

그리고 "Filename"이 잘못된 필드라고 가정 해 봅시다. 
이제 (TQuery 컴포넌트에서 필드를 제거해야합니다!) TEXT를 VARCHAR로 캐스팅하여 쿼리를 변경하십시오.





5
SELECT 
  CAST "Filename" AS VARCHAR AS "Filename" 
  "Date" 
FROM 
  "mytable" ;

이제 실제 텍스트가 표시되고 "(메모)"텍스트는 표시되지 않습니다.

옵션 2 (옵션 1 실패시) - OnGetText 이벤트

이것은 런타임에만 작동하며 조금 더 많은 작업이 필요합니다.

먼저 TQuery에 필드를 추가해야합니다. 
TQuery를 마우스 오른쪽 단추로 클릭하고 "Edit Fields"를 선택하십시오. 
다음 창에서 "+"버튼을 클릭하여 "(메모)"로 표시된 필드를 추가하십시오.

이제 새로 추가 된 필드를 클릭하십시오. TMemoField가 오브젝트 인스펙터에 추가 된 것을 볼 수 있습니다. 
오브젝트 인스펙터에서 "이벤트"탭을 클릭하고 "OnGetText"이벤트를 두 번 클릭하십시오.

이제이 코드를 이벤트 처리기에 추가합니다 (Tryery = qrySomeQuery, fieldname = "SomeField", "qrySomeQuerySomeField"라는 TMemoField를 생성 함).


2
aText = 보낸 사람 AsString 
DisplayText true ;

그래서 우리는 다음과 같은 것을 얻습니다. (실행시에) 대신에 실제 텍스트를 보여줍니다. if (memo) :





5
TForm1 프로 시저 qrySomeQuerySomeFieldGetText ( 보낸 사람 : TField var aText 문자열 , DisplayText 부울 
begin
  aText = Sender AsString 
  DisplayText true 
끝 ;

자동 증가 필드 재설정

SQLite에서 테이블을 비우거나 많은 레코드를 제거 할 때 자동 증가 필드 카운터 (1 또는 사용 가능한 다음 사용 가능한 번호)를 재설정 할 수 있습니다.

다음 SQL 문은 모든 테이블에 대해이 작업을 수행합니다 (예 : 안전합니다. 테이블의 레코드는 삭제되거나 수정되지 않습니다).

1
DELETE FROM sqlite_sequence;

또는 특정 테이블에 대해 이렇게 :

1
DELETE FROM sqlite_sequence WHERE name 'your_table' ;

데이터베이스 파일 압축 (진공)

이 것은 꽤 까다 롭습니다. 즉, 런타임에 데이터베이스를 정리하고 압축하는 것이지만, Lazarus 포럼 에서 발견 한 약간 수정 된 트릭이  가능합니다. 
일반적으로 TSQLQuery 구성 요소를 통해 "VACUUM"문을 실행하려고 하면 오류 메시지 ( 트랜잭션 내에서 오류를 일으킬 수 없음)가 표시됩니다.

먼저 Uses "절에 sqlite3ds " 단위를 추가하십시오 .

그런 다음 코드에서이 프로 시저를 추가하고 호출하십시오. 
기존 TSQLite3Connection의 이름 (SQLite와 매우 공통적 인 하나만 사용한다고 가정), 연결을 닫고 데이터베이스를 압축 (압축) 한 다음이 함수를 호출했을 때 열려 있으면 TSQLite3Connection을 복원합니다.










10 
11 
12 
13 
14 
15 
16 
17
TForm1 프로 시저 SQLiteVacuum ( db : TSQLite3Connection 
var tmpDataset   : TSqlite3Dataset 
    wasConnected boolean 
시작
  wasConnected = db 연결됨 

  db 닫기 db가 아닐 때까지 
  반복 하십시오 연결됨   tmpDataset = TSqlite3Dataset 생성 nil )
  


  tmpDataset FileName = SQLConnection DatabaseName 
  tmpDataset ExecSQL 'VACUUM;' 
  tmpDataset 무료 

  db 연결됨 = wasConnected 
끝 ;

숫자로 텍스트 주문

SQLite에서 텍스트를 숫자로 정렬하려고하면 숫자를 정렬하지 않는 몇 가지 문제가 발생합니다. 
작은 트릭을 사용하면 숫자가있는 필드의 경우 숫자로 텍스트를 주문할 수 있습니다. 
필자의 예에서는 480p ", " 720p ", " 1080p "및 " 2160p " 와 같은 값을 가진 video_mode " 필드가 있습니다. ORDER BY video_mode " 를 사용하여 정상적인 정렬 이 실패하고 결과는 다음과 같습니다.

1080p
2160p
480p
720p

정확히 수치가 아니거나 (일명 "자연"), 적어도 우리가 예상했던 방식은 아닙니다 ....

그러나 CAST를 INTEGER에 추가하면 (ORDER BY에서) 필드에 텍스트가 있더라도 숫자 정렬이 수행됩니다.

ORDER BY CAST (video_mode AS INTEGER)
또는 
ORDER BY CAST (video_mode AS DECIMAL)

결과는 원하는 순서입니다.

480p
720p
1080p
2160p

텍스트 정렬, 대소 문자를 구분하지 않음

필드에서 ORDER BY를 할 때, 예를 들어 다음 값을 가진 "title"이라고 말하면,

표제
-----
 기음
 에이
 엑스

그 다음으로 :

SELECT ... 주문 제목 ASC;

당신은 얻을 것이다:


 엑스
 에이
 기음

이 대소 문자를 구분하지 않고 사용하려면 다음과 같이하십시오.

SELECT ... 제목으로 주문 COLLATE NOCASE ASC ;

올바른 순서를 얻을 수 있습니다.

 에이
 기음
 엑스

추가 리소스

Lazarus와 SQLite를 파헤치는 데 유용하다면 도움이 될만한 몇 가지 추가 자료 :