| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.IO;
- using System.Text;
- using System.Windows.Forms;
- using Npgsql;
- using NpgsqlTypes;
- namespace SimpleDBViewer
- {
- public partial class MainForm : Form
- {
- public const string DbSchema = "akulova_vs";
- private readonly List<TableInfo> tableInfos = new List<TableInfo>();
- private TableInfo currentTable;
- private DataTable currentTableData;
- private DataTable currentSearchData;
- public MainForm()
- {
- bool isDesigner = LicenseManager.UsageMode == LicenseUsageMode.Designtime;
- if (!isDesigner && !UserSession.IsLoggedIn)
- {
- MessageBox.Show("Сначала выполните вход в систему.", "Доступ запрещён",
- MessageBoxButtons.OK, MessageBoxIcon.Warning);
- Close();
- return;
- }
- InitializeComponent();
- if (isDesigner)
- return;
- BuildTableList();
- ApplyPermissions();
- LoadInitialData();
- }
- private void BuildTableList()
- {
- tableInfos.Clear();
- if (!UserSession.IsAdmin)
- {
- tableInfos.Add(new TableInfo("personal_profile", "Мои данные", "driver_id"));
- tableInfos.Add(new TableInfo("personal_exams", "Мои экзамены", "exam_id"));
- tableInfos.Add(new TableInfo("personal_license", "Моё удостоверение", "license_id"));
- return;
- }
- tableInfos.Add(new TableInfo("driving_schools", "Автошколы", "school_id"));
- tableInfos.Add(new TableInfo("instructors", "Инструкторы", "instructor_id"));
- tableInfos.Add(new TableInfo("drivers", "Водители", "driver_id"));
- tableInfos.Add(new TableInfo("exam_routes", "Маршруты экзамена", "route_id"));
- tableInfos.Add(new TableInfo("traffic_inspectors", "Инспекторы", "inspector_id"));
- tableInfos.Add(new TableInfo("traffic_officers", "Сотрудники, выдающие права", "officer_id"));
- tableInfos.Add(new TableInfo("exams", "Экзамены", "exam_id"));
- tableInfos.Add(new TableInfo("licenses", "Водительские удостоверения", "license_id"));
- tableInfos.Add(new TableInfo("app_users", "Пользователи приложения", "user_id"));
- tableInfos.Add(new TableInfo("audit_log", "Журнал операций", "log_id", true));
- }
- private void ApplyPermissions()
- {
- lblUser.Text = UserSession.CurrentUser.Login + " · " + UserSession.CurrentUser.Role;
- bool isAdmin = UserSession.IsAdmin;
- btnAdd.Enabled = isAdmin;
- btnEdit.Enabled = isAdmin;
- btnDelete.Enabled = isAdmin;
- if (!isAdmin)
- {
- lblTitle.Text = "Личный кабинет автошколы";
- lblTableCaption.Text = "Раздел:";
- tabTables.Text = "Личный кабинет";
- btnAdd.Visible = false;
- btnEdit.Visible = false;
- btnDelete.Visible = false;
- btnExportTable.Location = btnAdd.Location;
- if (tabControl.TabPages.Contains(tabSearch))
- tabControl.TabPages.Remove(tabSearch);
- }
- UpdateActionButtons();
- }
- private void UpdateActionButtons()
- {
- bool canModify = UserSession.IsAdmin && currentTable != null && !currentTable.IsReadOnly;
- if (btnAdd != null) btnAdd.Enabled = canModify;
- if (btnEdit != null) btnEdit.Enabled = canModify;
- if (btnDelete != null) btnDelete.Enabled = canModify;
- }
- private void LoadInitialData()
- {
- cmbTables.Items.Clear();
- foreach (TableInfo table in tableInfos)
- {
- cmbTables.Items.Add(table);
- }
- if (cmbTables.Items.Count > 0)
- {
- cmbTables.SelectedIndex = 0;
- }
- if (UserSession.IsAdmin)
- LoadExamSearch();
- }
- private void CmbTables_SelectedIndexChanged(object sender, EventArgs e)
- {
- currentTable = cmbTables.SelectedItem as TableInfo;
- UpdateActionButtons();
- LoadCurrentTable();
- }
- private void LoadCurrentTable()
- {
- if (currentTable == null)
- return;
- try
- {
- using (NpgsqlConnection connection = new NpgsqlConnection(DbSettings.ConnectionString))
- {
- connection.Open();
- string sql = GetSelectSql(currentTable);
- using (NpgsqlCommand command = new NpgsqlCommand(sql, connection))
- {
- AddCurrentTableParameters(command);
- using (NpgsqlDataAdapter adapter = new NpgsqlDataAdapter(command))
- {
- currentTableData = new DataTable();
- adapter.Fill(currentTableData);
- dgvTables.DataSource = currentTableData;
- ApplyGridPresentation(dgvTables);
- lblTableStatus.Text = currentTable.DisplayName + ": записей — " + currentTableData.Rows.Count;
- }
- }
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(AppError.ToUserMessage(ex, "Не удалось загрузить таблицу."),
- "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
- private void AddCurrentTableParameters(NpgsqlCommand command)
- {
- if (currentTable == null)
- return;
- if (currentTable.Name == "personal_profile" || currentTable.Name == "personal_exams" || currentTable.Name == "personal_license")
- {
- int driverId = UserSession.CurrentUser != null && UserSession.CurrentUser.DriverId.HasValue
- ? UserSession.CurrentUser.DriverId.Value
- : -1;
- command.Parameters.AddWithValue("@current_driver_id", driverId);
- }
- }
- private string GetSelectSql(TableInfo table)
- {
- if (table.Name == "personal_profile")
- {
- if (GetCurrentDriverCondition() == null)
- return "select 'Учётная запись не привязана к водителю. Обратитесь к администратору.' as message";
- return @"select d.driver_id,
- concat_ws(' ', d.last_name, d.first_name, d.middle_name) as driver_display,
- d.birth_date,
- d.phone,
- ds.school_name
- from akulova_vs.drivers d
- join akulova_vs.driving_schools ds on ds.school_id = d.school_id
- where d.driver_id = @current_driver_id";
- }
- if (table.Name == "personal_exams")
- {
- if (GetCurrentDriverCondition() == null)
- return "select 'Учётная запись не привязана к водителю. Обратитесь к администратору.' as message";
- return @"select exam_id,
- exam_date,
- result,
- route_name,
- inspector_full_name,
- attempt_number,
- driver_age
- from (
- select e.exam_id,
- e.exam_date,
- e.result,
- r.route_name,
- concat_ws(' ', ti.last_name, ti.first_name, ti.middle_name) as inspector_full_name,
- count(*) over (
- partition by e.driver_id
- order by e.exam_date, e.exam_id
- rows between unbounded preceding and current row
- )::integer as attempt_number,
- extract(year from age(e.exam_date, d.birth_date))::integer as driver_age
- from akulova_vs.exams e
- join akulova_vs.drivers d on d.driver_id = e.driver_id
- join akulova_vs.exam_routes r on r.route_id = e.route_id
- join akulova_vs.traffic_inspectors ti on ti.inspector_id = e.inspector_id
- where e.driver_id = @current_driver_id
- ) personal_exams
- order by exam_date desc, exam_id desc";
- }
- if (table.Name == "personal_license")
- {
- if (GetCurrentDriverCondition() == null)
- return "select 'Учётная запись не привязана к водителю. Обратитесь к администратору.' as message";
- return @"select l.license_id,
- l.issue_date,
- l.category,
- l.license_number,
- concat_ws(' ', o.last_name, o.first_name, o.middle_name) as officer_display
- from akulova_vs.licenses l
- join akulova_vs.traffic_officers o on o.officer_id = l.officer_id
- where l.driver_id = @current_driver_id
- order by l.issue_date desc, l.license_id desc";
- }
- if (table.Name == "driving_schools")
- {
- return @"select school_id, school_name, address, phone
- from akulova_vs.driving_schools
- order by school_id";
- }
- if (table.Name == "instructors")
- {
- return @"select i.instructor_id, i.school_id, ds.school_name as school_display,
- i.last_name, i.first_name, i.middle_name, i.phone, i.license_number
- from akulova_vs.instructors i
- join akulova_vs.driving_schools ds on ds.school_id = i.school_id
- order by i.instructor_id";
- }
- if (table.Name == "drivers")
- {
- return @"select d.driver_id, d.school_id, ds.school_name as school_display,
- d.last_name, d.first_name, d.middle_name, d.birth_date, d.phone
- from akulova_vs.drivers d
- join akulova_vs.driving_schools ds on ds.school_id = d.school_id
- order by d.driver_id";
- }
- if (table.Name == "exam_routes")
- {
- return @"select route_id, route_name, start_address, end_address, difficulty
- from akulova_vs.exam_routes
- order by route_id";
- }
- if (table.Name == "traffic_inspectors")
- {
- return @"select inspector_id, last_name, first_name, middle_name, rank_name
- from akulova_vs.traffic_inspectors
- order by inspector_id";
- }
- if (table.Name == "traffic_officers")
- {
- return @"select officer_id, last_name, first_name, middle_name, position_name
- from akulova_vs.traffic_officers
- order by officer_id";
- }
- if (table.Name == "exams")
- {
- return @"select e.exam_id,
- e.driver_id, concat_ws(' ', d.last_name, d.first_name, d.middle_name) as driver_display,
- e.route_id, r.route_name as route_display,
- e.inspector_id, concat_ws(' ', ti.last_name, ti.first_name, ti.middle_name) as inspector_display,
- e.exam_date, e.result
- from akulova_vs.exams e
- join akulova_vs.drivers d on d.driver_id = e.driver_id
- join akulova_vs.exam_routes r on r.route_id = e.route_id
- join akulova_vs.traffic_inspectors ti on ti.inspector_id = e.inspector_id
- order by e.exam_id";
- }
- if (table.Name == "licenses")
- {
- return @"select l.license_id,
- l.driver_id, concat_ws(' ', d.last_name, d.first_name, d.middle_name) as driver_display,
- l.officer_id, concat_ws(' ', o.last_name, o.first_name, o.middle_name) as officer_display,
- l.issue_date, l.category, l.license_number
- from akulova_vs.licenses l
- join akulova_vs.drivers d on d.driver_id = l.driver_id
- join akulova_vs.traffic_officers o on o.officer_id = l.officer_id
- order by l.license_id";
- }
- if (table.Name == "app_users")
- {
- return @"select u.user_id, u.login, u.role::text as role, u.is_active,
- u.instructor_id, concat_ws(' ', i.last_name, i.first_name, i.middle_name) as instructor_display,
- u.driver_id, concat_ws(' ', d.last_name, d.first_name, d.middle_name) as driver_display
- from akulova_vs.app_users u
- left join akulova_vs.instructors i on i.instructor_id = u.instructor_id
- left join akulova_vs.drivers d on d.driver_id = u.driver_id
- order by u.user_id";
- }
- if (table.Name == "audit_log")
- {
- return @"select log_id,
- table_name,
- operation,
- record_id,
- changed_at,
- coalesce(nullif(changed_by, ''), 'system') as changed_by
- from akulova_vs.audit_log
- order by changed_at desc, log_id desc
- limit 500";
- }
- return "select * from " + FullName(table.Name) + " order by " + Quote(table.PrimaryKey);
- }
- private string GetCurrentDriverCondition()
- {
- if (UserSession.CurrentUser == null || !UserSession.CurrentUser.DriverId.HasValue)
- return null;
- return UserSession.CurrentUser.DriverId.Value.ToString();
- }
- private void ApplyGridPresentation(DataGridView grid)
- {
- if (grid == null)
- return;
- foreach (DataGridViewColumn column in grid.Columns)
- {
- string name = column.Name;
- column.Visible = !IsTechnicalColumn(name);
- column.HeaderText = GetColumnCaption(name);
- if (name.EndsWith("_date", StringComparison.OrdinalIgnoreCase) || name == "birth_date" || name == "exam_date" || name == "issue_date")
- column.DefaultCellStyle.Format = "dd.MM.yyyy";
- }
- grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
- grid.AutoResizeColumns();
- }
- private bool IsTechnicalColumn(string columnName)
- {
- if (string.IsNullOrEmpty(columnName))
- return false;
- if (columnName == "password_hash")
- return true;
- if (columnName == "record_id")
- return false;
- if (columnName.EndsWith("_id", StringComparison.OrdinalIgnoreCase))
- return true;
- return false;
- }
- private string GetColumnCaption(string columnName)
- {
- Dictionary<string, string> captions = new Dictionary<string, string>
- {
- { "school_name", "Название автошколы" },
- { "address", "Адрес" },
- { "phone", "Телефон" },
- { "school_display", "Автошкола" },
- { "last_name", "Фамилия" },
- { "first_name", "Имя" },
- { "middle_name", "Отчество" },
- { "license_number", "Номер удостоверения" },
- { "birth_date", "Дата рождения" },
- { "route_name", "Название маршрута" },
- { "route_display", "Маршрут" },
- { "start_address", "Начальный адрес" },
- { "end_address", "Конечный адрес" },
- { "difficulty", "Сложность" },
- { "rank_name", "Звание" },
- { "position_name", "Должность" },
- { "driver_display", "Водитель" },
- { "message", "Сообщение" },
- { "inspector_display", "Инспектор" },
- { "officer_display", "Сотрудник" },
- { "exam_date", "Дата экзамена" },
- { "result", "Результат" },
- { "issue_date", "Дата выдачи" },
- { "category", "Категория" },
- { "login", "Логин" },
- { "role", "Роль" },
- { "is_active", "Активен" },
- { "instructor_display", "Инструктор" },
- { "driver_full_name", "Водитель" },
- { "inspector_full_name", "Инспектор" },
- { "attempt_number", "Попытка №" },
- { "driver_age", "Возраст водителя" },
- { "table_name", "Таблица" },
- { "operation", "Операция" },
- { "record_id", "ID записи" },
- { "changed_at", "Дата и время" },
- { "changed_by", "Пользователь" }
- };
- return captions.ContainsKey(columnName) ? captions[columnName] : columnName;
- }
- private void BtnRefresh_Click(object sender, EventArgs e)
- {
- LoadCurrentTable();
- }
- private void BtnAdd_Click(object sender, EventArgs e)
- {
- if (!UserSession.IsAdmin)
- {
- ShowReadonlyMessage();
- return;
- }
- if (currentTable == null)
- return;
- if (currentTable.IsReadOnly)
- {
- MessageBox.Show("Этот раздел предназначен только для просмотра.", "Информация",
- MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- using (RecordEditForm form = new RecordEditForm(DbSettings.ConnectionString, currentTable, null))
- {
- if (form.ShowDialog(this) == DialogResult.OK)
- {
- LoadCurrentTable();
- LoadExamSearch();
- }
- }
- }
- private void BtnEdit_Click(object sender, EventArgs e)
- {
- if (!UserSession.IsAdmin)
- {
- ShowReadonlyMessage();
- return;
- }
- if (currentTable != null && currentTable.IsReadOnly)
- {
- MessageBox.Show("Этот раздел предназначен только для просмотра.", "Информация",
- MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- if (currentTable == null || dgvTables.SelectedRows.Count == 0)
- {
- MessageBox.Show("Выберите запись для изменения.", "Информация",
- MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- DataRowView rowView = dgvTables.SelectedRows[0].DataBoundItem as DataRowView;
- if (rowView == null)
- return;
- using (RecordEditForm form = new RecordEditForm(DbSettings.ConnectionString, currentTable, rowView.Row))
- {
- if (form.ShowDialog(this) == DialogResult.OK)
- {
- LoadCurrentTable();
- LoadExamSearch();
- }
- }
- }
- private void BtnDelete_Click(object sender, EventArgs e)
- {
- if (!UserSession.IsAdmin)
- {
- ShowReadonlyMessage();
- return;
- }
- if (currentTable != null && currentTable.IsReadOnly)
- {
- MessageBox.Show("Этот раздел предназначен только для просмотра.", "Информация",
- MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- if (currentTable == null || dgvTables.SelectedRows.Count == 0)
- {
- MessageBox.Show("Выберите запись для удаления.", "Информация",
- MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- DataRowView rowView = dgvTables.SelectedRows[0].DataBoundItem as DataRowView;
- if (rowView == null)
- return;
- object pkValue = rowView.Row[currentTable.PrimaryKey];
- if (currentTable.Name == "app_users" && Convert.ToInt32(pkValue) == UserSession.CurrentUser.UserId)
- {
- MessageBox.Show("Нельзя удалить текущую учётную запись, под которой выполнен вход.",
- "Удаление запрещено", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- DialogResult result = MessageBox.Show("Удалить выбранную запись?",
- "Подтверждение", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
- if (result != DialogResult.Yes)
- return;
- try
- {
- using (NpgsqlConnection connection = new NpgsqlConnection(DbSettings.ConnectionString))
- {
- connection.Open();
- DbAppContext.Apply(connection);
- string sql = "delete from " + FullName(currentTable.Name) + " where " + Quote(currentTable.PrimaryKey) + " = @id";
- using (NpgsqlCommand command = new NpgsqlCommand(sql, connection))
- {
- command.Parameters.AddWithValue("@id", pkValue);
- command.ExecuteNonQuery();
- DbAppContext.MarkLatestAuditLogin(connection, currentTable.Name, pkValue);
- }
- }
- LoadCurrentTable();
- LoadExamSearch();
- }
- catch (Exception ex)
- {
- MessageBox.Show(AppError.ToUserMessage(ex, "Не удалось удалить запись."),
- "Ошибка удаления", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
- private void ShowReadonlyMessage()
- {
- MessageBox.Show("Обычный пользователь работает только с личным кабинетом. Изменение данных доступно только роли admin.",
- "Недостаточно прав", MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- private void BtnExportTable_Click(object sender, EventArgs e)
- {
- ExportTable(dgvTables, currentTable == null ? "table" : currentTable.Name);
- }
- private void BtnSearch_Click(object sender, EventArgs e)
- {
- LoadExamSearch();
- }
- private void BtnReset_Click(object sender, EventArgs e)
- {
- txtDriverFilter.Clear();
- txtSchoolFilter.Clear();
- cmbResultFilter.SelectedIndex = 0;
- dtFrom.Checked = false;
- dtTo.Checked = false;
- LoadExamSearch();
- }
- private void BtnExportSearch_Click(object sender, EventArgs e)
- {
- ExportTable(dgvSearch, "exam_search");
- }
- private void LoadExamSearch()
- {
- try
- {
- using (NpgsqlConnection connection = new NpgsqlConnection(DbSettings.ConnectionString))
- {
- connection.Open();
- const string sql = @"
- select exam_id, exam_date, result, driver_full_name, school_name, route_name, inspector_full_name, attempt_number, driver_age
- from akulova_vs.v_exam_search
- where (cast(@driver as text) = '' or driver_full_name ilike '%' || cast(@driver as text) || '%')
- and (cast(@school as text) = '' or school_name ilike '%' || cast(@school as text) || '%')
- and (cast(@result as text) = '' or result = cast(@result as text))
- and (cast(@date_from as date) is null or exam_date >= cast(@date_from as date))
- and (cast(@date_to as date) is null or exam_date <= cast(@date_to as date))
- order by exam_date desc, exam_id desc;";
- using (NpgsqlCommand command = new NpgsqlCommand(sql, connection))
- {
- command.Parameters.AddWithValue("@driver", txtDriverFilter == null ? "" : txtDriverFilter.Text.Trim());
- command.Parameters.AddWithValue("@school", txtSchoolFilter == null ? "" : txtSchoolFilter.Text.Trim());
- string selectedResult = cmbResultFilter == null || cmbResultFilter.SelectedIndex <= 0
- ? ""
- : cmbResultFilter.SelectedItem.ToString();
- command.Parameters.AddWithValue("@result", selectedResult);
- Npgsql.NpgsqlParameter dateFromParameter = command.Parameters.Add("@date_from", NpgsqlTypes.NpgsqlDbType.Date);
- dateFromParameter.Value = dtFrom != null && dtFrom.Checked ? (object)dtFrom.Value.Date : DBNull.Value;
- Npgsql.NpgsqlParameter dateToParameter = command.Parameters.Add("@date_to", NpgsqlTypes.NpgsqlDbType.Date);
- dateToParameter.Value = dtTo != null && dtTo.Checked ? (object)dtTo.Value.Date : DBNull.Value;
- using (NpgsqlDataAdapter adapter = new NpgsqlDataAdapter(command))
- {
- currentSearchData = new DataTable();
- adapter.Fill(currentSearchData);
- if (dgvSearch != null)
- {
- dgvSearch.DataSource = currentSearchData;
- ApplyGridPresentation(dgvSearch);
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- if (dgvSearch != null)
- {
- MessageBox.Show(AppError.ToUserMessage(ex, "Не удалось выполнить поиск по экзаменам."),
- "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
- }
- private void ExportTable(DataGridView grid, string filePrefix)
- {
- if (grid == null || grid.DataSource == null || grid.Rows.Count == 0)
- {
- MessageBox.Show("Нет данных для экспорта.", "Информация",
- MessageBoxButtons.OK, MessageBoxIcon.Information);
- return;
- }
- using (SaveFileDialog dialog = new SaveFileDialog())
- {
- dialog.Filter = "CSV файл (*.csv)|*.csv";
- dialog.FileName = filePrefix + "_" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".csv";
- if (dialog.ShowDialog(this) != DialogResult.OK)
- return;
- try
- {
- WriteCsv(grid, dialog.FileName);
- MessageBox.Show("CSV-файл сохранён:\n" + dialog.FileName,
- "Экспорт выполнен", MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- catch (Exception ex)
- {
- MessageBox.Show("Не удалось сохранить CSV.\n\n" + ex.Message,
- "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
- }
- private void WriteCsv(DataGridView grid, string path)
- {
- List<DataGridViewColumn> visibleColumns = new List<DataGridViewColumn>();
- foreach (DataGridViewColumn column in grid.Columns)
- {
- if (column.Visible)
- visibleColumns.Add(column);
- }
- using (StreamWriter writer = new StreamWriter(path, false, new UTF8Encoding(true)))
- {
- for (int i = 0; i < visibleColumns.Count; i++)
- {
- if (i > 0) writer.Write(';');
- writer.Write(EscapeCsv(visibleColumns[i].HeaderText));
- }
- writer.WriteLine();
- foreach (DataGridViewRow row in grid.Rows)
- {
- if (row.IsNewRow)
- continue;
- for (int i = 0; i < visibleColumns.Count; i++)
- {
- if (i > 0) writer.Write(';');
- object value = row.Cells[visibleColumns[i].Name].Value;
- writer.Write(EscapeCsv(value == null || value == DBNull.Value ? "" : value.ToString()));
- }
- writer.WriteLine();
- }
- }
- }
- private string EscapeCsv(string value)
- {
- if (value == null) return "";
- bool needQuotes = value.Contains(";") || value.Contains("\"") || value.Contains("\n") || value.Contains("\r");
- value = value.Replace("\"", "\"\"");
- return needQuotes ? "\"" + value + "\"" : value;
- }
- private void BtnLogout_Click(object sender, EventArgs e)
- {
- UserSession.Logout();
- Close();
- }
- public static string FullName(string identifier)
- {
- return Quote(DbSchema) + "." + Quote(identifier);
- }
- public static string Quote(string identifier)
- {
- return "\"" + identifier.Replace("\"", "\"\"") + "\"";
- }
- }
- public class TableInfo
- {
- public string Name { get; private set; }
- public string DisplayName { get; private set; }
- public string PrimaryKey { get; private set; }
- public bool IsReadOnly { get; private set; }
- public TableInfo(string name, string displayName, string primaryKey)
- : this(name, displayName, primaryKey, false)
- {
- }
- public TableInfo(string name, string displayName, string primaryKey, bool isReadOnly)
- {
- Name = name;
- DisplayName = displayName;
- PrimaryKey = primaryKey;
- IsReadOnly = isReadOnly;
- }
- public override string ToString()
- {
- return DisplayName;
- }
- }
- public class ColumnInfo
- {
- public string Name { get; set; }
- public string DataType { get; set; }
- public string UdtName { get; set; }
- public bool IsNullable { get; set; }
- public bool IsIdentity { get; set; }
- public bool IsPrimaryKey { get; set; }
- }
- public class ComboItem
- {
- public int? Id { get; private set; }
- public string Text { get; private set; }
- public ComboItem(int? id, string text)
- {
- Id = id;
- Text = text;
- }
- public override string ToString()
- {
- return Text;
- }
- }
- public class FieldBinding
- {
- public ColumnInfo Column { get; set; }
- public Control Control { get; set; }
- public bool IsPasswordField { get; set; }
- }
- }
|