165 lines
8.4 KiB
Plaintext
165 lines
8.4 KiB
Plaintext
<!---
|
||
Application.cfc — конфигурация Lucee CRUD-приложения
|
||
|
||
Жизненный цикл:
|
||
1. OnApplicationStart — вызывается ОДИН раз при старте приложения
|
||
- читает TABLE_NAME из env vars (json_env в Terraform)
|
||
- создаёт таблицу CREATE TABLE IF NOT EXISTS
|
||
- сохраняет имя таблицы в application.tableName
|
||
2. OnRequestStart — вызывается ПЕРЕД каждым запросом
|
||
- копирует application.tableName → request.tableName
|
||
3. OnRequest — вызывает index.cfm с CRUD-логикой
|
||
|
||
Datasource: testds, конфигурируется из env vars с префиксом testds_
|
||
(testds_class, testds_connectionString, testds_username, testds_password, ...)
|
||
|
||
Terraform json_env должен содержать:
|
||
- TABLE_NAME — имя таблицы (по умолчанию check_point)
|
||
- testds_class — JDBC-драйвер
|
||
- testds_connectionString — строка подключения к PostgreSQL
|
||
- testds_username — имя пользователя БД
|
||
- testds_password — пароль пользователя БД
|
||
--->
|
||
<cfcomponent displayname="Application" output="true">
|
||
|
||
<!--- Идентификатор приложения для Lucee --->
|
||
<cfset this.Name = "tfluceecrud" />
|
||
|
||
<!--- Таймаут приложения: 3 часа бездействия → перезапуск (вызовет OnApplicationStart заново) --->
|
||
<cfset this.applicationTimeout = createTimeSpan(0, 0, 3, 0) />
|
||
|
||
<!--- Включаем сессии для защиты от CSRF (Lucee автоматически добавляет токены) --->
|
||
<cfset this.sessionmanagement = "Yes" />
|
||
|
||
<!--- Сессия живёт 2 часа неактивности --->
|
||
<cfset this.sessiontimeout = CreateTimeSpan(0, 0, 120, 0) />
|
||
|
||
<!--- Имя datasource по умолчанию — используется в cfquery без атрибута datasource --->
|
||
<cfset this.datasource = "testds" />
|
||
|
||
<!--- Конфигурируем datasource из env vars с префиксом testds_ --->
|
||
<cfset getDS(this.datasource, this.datasource) />
|
||
|
||
<!--- Отключаем отладку на проде, таймаут запроса 20 секунд --->
|
||
<cfsetting requesttimeout="20" showdebugoutput="false" />
|
||
|
||
|
||
<!---
|
||
OnApplicationStart — выполняется ОДИН раз при старте приложения.
|
||
Здесь: создаём таблицу если её нет, сохраняем имя в application scope.
|
||
|
||
application scope — живёт пока приложение не перезапустится (таймаут 3 часа).
|
||
Используем application а не request потому что request умирает после каждого запроса.
|
||
--->
|
||
<cffunction name="OnApplicationStart" access="public" returntype="boolean">
|
||
<!--- 1. Читаем имя таблицы из переменной окружения TABLE_NAME --->
|
||
<cfset var tableName = createObject("java", "java.lang.System").getEnv().get("TABLE_NAME") />
|
||
|
||
<!--- 2. Если переменная не задана в json_env — используем значение по умолчанию --->
|
||
<cfif NOT isDefined("tableName") OR NOT len(tableName)>
|
||
<cfset tableName = "check_point" />
|
||
</cfif>
|
||
|
||
<!--- 3. Сохраняем в application scope — доступно всем запросам этого приложения --->
|
||
<cfset application.tableName = tableName />
|
||
|
||
<!--- 4. Создаём таблицу если она ещё не существует --->
|
||
<!--- id: автоинкрементный первичный ключ --->
|
||
<!--- value: текстовое поле для CRUD-значений --->
|
||
<cftry>
|
||
<cfquery>
|
||
CREATE TABLE IF NOT EXISTS #tableName# (
|
||
id SERIAL PRIMARY KEY,
|
||
value TEXT NOT NULL DEFAULT ''
|
||
)
|
||
</cfquery>
|
||
<!--- Игнорируем ошибки: нет прав, БД недоступна --->
|
||
<cfcatch type="database"></cfcatch>
|
||
</cftry>
|
||
|
||
<cfreturn true />
|
||
</cffunction>
|
||
|
||
|
||
<!---
|
||
OnRequestStart — выполняется ПЕРЕД каждым HTTP-запросом.
|
||
Здесь: копируем имя таблицы из application в request scope.
|
||
|
||
request scope — живёт только в течение одного запроса.
|
||
Каждая страница (index.cfm) читает request.tableName.
|
||
--->
|
||
<cffunction name="OnRequestStart" access="public" returntype="boolean">
|
||
<!--- Если приложение уже стартовало — берём имя из application --->
|
||
<cfif isDefined("application.tableName")>
|
||
<cfset request.tableName = application.tableName />
|
||
<!--- Иначе (первый запрос до OnApplicationStart) — fallback --->
|
||
<cfelse>
|
||
<cfset request.tableName = "check_point" />
|
||
</cfif>
|
||
|
||
<cfreturn true />
|
||
</cffunction>
|
||
|
||
|
||
<!---
|
||
OnRequest — обработчик каждого запроса.
|
||
Включает целевой шаблон (index.cfm) с установленной кодировкой.
|
||
--->
|
||
<cffunction name="OnRequest" access="public" returntype="void">
|
||
<cfargument name="template" type="string" required="true" />
|
||
|
||
<!--- UTF-8 для форм и URL-параметров --->
|
||
<cfset setEncoding("FORM", "UTF-8") />
|
||
<cfset setEncoding("URL", "UTF-8") />
|
||
|
||
<!--- Вычисляем web-корень для ссылок --->
|
||
<cfset local.basePath = getDirectoryFromPath(getCurrentTemplatePath()) />
|
||
<cfset request.webRoot = "../" />
|
||
<cfset request.thisPage = Replace(ReplaceNoCase(expandPath(arguments.template), local.basePath, ""), "\", "/") />
|
||
|
||
<!--- Выполняем запрошенный шаблон (index.cfm) --->
|
||
<cfinclude template="#arguments.template#" />
|
||
</cffunction>
|
||
|
||
|
||
<!---
|
||
getDS — конфигурирует datasource Lucee из переменных окружения.
|
||
|
||
Соглашение об именах env vars:
|
||
{prefix}_{field} → параметр datasource
|
||
|
||
Пример для testds:
|
||
testds_class → JDBC-драйвер
|
||
testds_connectionString → jdbc:postgresql://host:5432/db
|
||
testds_username → пользователь
|
||
testds_password → пароль
|
||
|
||
Все параметры передаются через json_env в Terraform.
|
||
--->
|
||
<cffunction name="getDS" access="private" returntype="void">
|
||
<cfargument name="dsname" type="string" required="true" hint="Имя datasource (testds)" />
|
||
<cfargument name="prefix" type="string" default="#dsname#" hint="Префикс env vars" />
|
||
|
||
<!--- Java-объект для чтения переменных окружения --->
|
||
<cfset var system = createObject("java", "java.lang.System") />
|
||
|
||
<!--- Словарь параметров datasource --->
|
||
<cfset var ds = {} />
|
||
|
||
<!--- Перебираем все возможные поля datasource --->
|
||
<cfloop list="class,connectionString,username,password,bundleName,bundleVersion,connectionLimit,liveTimeout,validate" item="field">
|
||
<!--- Читаем env var: {prefix}_{field}, например testds_username --->
|
||
<cfset var value = system.getEnv("#arguments.prefix#_#field#") />
|
||
|
||
<!--- Если переменная задана и не пуста — добавляем в datasource --->
|
||
<cfif isDefined("value") AND len(value)>
|
||
<cfset structInsert(ds, field, value) />
|
||
</cfif>
|
||
</cfloop>
|
||
|
||
<!--- Регистрируем datasource в Lucee --->
|
||
<cfset THIS.datasources[dsname] = ds />
|
||
</cffunction>
|
||
|
||
</cfcomponent>
|